documentationfor yFiles for HTML 2.6

Migrating to 2.0 from 1.x

This chapter presents the necessary steps to migrate applications based on yFiles for HTML 1.4 to yFiles for HTML 2.x.

The 2.x release of yFiles for HTML updates the general API concepts to that of yFiles for Java 3.x and is an evolutionary step from yFiles for HTML 1.4 and older. While for the 1.0 release of yFiles for HTML API-compatibility and similarity with our WPF-, Silverlight-, and Windows Forms-based solutions was an important point, the 2.x release makes the API a lot easier and pleasant to work with for developers that come from a different background and expect an API that is more in line with what they are used to know from the modern JavaScript-based development.

The 2.x release is backwards-incompatible to 1.4, but the most frequently used API has been preserved and the concepts are still the same. Thus, a lot of code can be migrated easily or does not require any migration at all.

Library Content

The yFiles for HTML 2.x library consists of the content in lib/, namely the library modules in lib/umd/ and lib/es-modules/ as well as the stylesheet lib/yfiles.css. Despite the new module structure in 2.x, this is similar to 1.x. Make sure to replace both, the modules together with their implementations in lib/umd/impl or lib/es-modules/ and the stylesheet.

General

Changes to the Class Framework

While the class framework is and was very powerful, yFiles for HTML 2.x does not use all of the advanced features of it anymore, making the API more in line with other popular JavaScript APIs. Working with yFiles lists the most important things you should know about the class framework.

The following advanced features of the class framework are not used by the public API in the library anymore:

  • Nested Types: Where previously interfaces, enumerations, and types could be nested in other interfaces and types, nested types have now all been moved to the top level. Where the naming of the type could be ambiguous, the names of the nested type has been adjusted.
  • Named Constructors: Types created by the class framework could have multiple, named constructors, simulating constructor overloads known from other languages. Named constructors aren’t used in the new version of the library anymore. If a type has a constructor, the type itself is the only constructor.

The following features have been added to the class framework and the library implementation that improve the developer experience when working with the APIs:

  • Constructor and Method Overloads: Previously similar methods with varying parameter lists had been mapped to functions of varying names, often resulting in longish function names. Similar methods are now implemented as overloads of a single function of the canonic name in most cases: Optional parameters with default values and true overloads with completely varying parameter type lists as well as rest arguments are now supported by the library. Parameter names have been made more consistent and in many places, "option" arguments can be used to pass arguments to a function using a concise single argument JavaScript Object notation.

// no argument
graphComponent = new GraphComponent()
// string argument overload with css selector or element id
graphComponent = new GraphComponent('#graphComponentDiv')
// element argument overload
graphComponent = new GraphComponent(document.getElementById('someId'))

// no arguments
graphComponent.graph.createNode()
// default/telescoping arguments
graphComponent.graph.createNode(new Rect(20, 20, 40, 40), new ShapeNodeStyle())
// option arguments
graphComponent.graph.createNode({
  style: new ShapeNodeStyle({
    shape: ShapeNodeShape.HEXAGON
  }),
  layout: new Rect(20, 20, 40, 40)
})
// no argument
graphComponent = new GraphComponent()
// string argument overload with css selector or element id
graphComponent = new GraphComponent('#graphComponentDiv')
// element argument overload
graphComponent = new GraphComponent(document.getElementById('someId') as HTMLDivElement)

// no arguments
graphComponent.graph.createNode()
// default/telescoping arguments
graphComponent.graph.createNode(new Rect(20, 20, 40, 40), new ShapeNodeStyle())
// option arguments
graphComponent.graph.createNode({
  style: new ShapeNodeStyle({
    shape: ShapeNodeShape.HEXAGON
  }),
  layout: new Rect(20, 20, 40, 40)
})
graphComponent.graph.createNode({
  layout: new Rect(20, 20, 40, 40),
  style: new ShapeNodeStyle({
    fill: Fill.BLUE,
    shape: ShapeNodeShape.ROUND_RECTANGLE
  })
})

  • Extra Arguments: Many factory-like methods and constructors that support the single "option" argument syntax in addition to the regular parameter list now also accept additional arguments that translate into setting additional properties or populating collections on the result of the method call. This allows for conveniently setting multiple properties on an instance of a type at construction time in the case of constructors or at creation time in the case of factory methods.

graphComponent.graph.createNode({
  labels: [
    {
      text: 'One Label',
      style: new DefaultLabelStyle({
        autoFlip: true,
        clipText: false,
        textFill: Fill.BLUE,
        wrapping: TextWrapping.CHARACTER
      })
    },
    { text: 'Second Label using defaults' }
  ]
})

  • Default Implementations for Methods and Properties: Interfaces can now contain default implementations of convenience methods as well as (computed) properties, which can be overridden by subclasses. This is known as "mixin" or "trait" behavior from other languages. Version 2.x uses default property implementations now where previously default getter style methods where used. This blurs the line between interface implementation and default mixins even more and results in a more consistent API where properties are more often implemented as properties and not as ordinary functions.

const rect = new Rect(20, 30, 50, 50)
console.log(rect.centerX + rect.topLeft.x)

  • Easy Interface Implementation: For simple interfaces there is now a convenient method available to create a proper implementations of the interface. The interface type now declares a constructor which can take a single function if the interface only requires a single abstract function to be implemented. For interfaces that contain more than one abstract member, an "option" argument needs to be passed to the interface constructor which contains an entry for each abstract member.

const hitTestable = IHitTestable.create((context, p) => p.x < 200)

const infiniteEnumerable = new IEnumerable(() => {
  return new IEnumerator({
    get current() {
      return 42
    },
    moveNext() {
      return true
    },
    reset() {}
  })
})

console.log(infiniteEnumerable.first((v) => v > 13))
const hitTestable = IHitTestable.create((context, p) => p.x < 200)

// @ts-ignore This is only a TS error but works in JS
const infiniteEnumerable = new IEnumerable((): any => {
  // @ts-ignore This is only a TS error but works in JS
  return new IEnumerator({
    get current(): number {
      return 42
    },
    moveNext(): boolean {
      return true
    },
    reset(): void {}
  })
}) as IEnumerable<number>

console.log(infiniteEnumerable.first((v) => v > 13))

  • ES2015-compliant Subclassing: The yFiles class framework now supports the ES2015 "class" keyword and also works with transpiled source code generated by TypeScript and other ES2015-compliant source code translation tools. This means that the use of the yFiles class framework is now discouraged for the simple subclassing use-case. Instead the corresponding subclassing feature of the language can be used and we encourage developers to use this mechanism when subclassing is required.

class MyGraphEditorInputMode extends GraphEditorInputMode {
  moving = false

  constructor() {
    super()
  }

  /**
   * @param {!IModelItem} item
   * @returns {boolean}
   */
  shouldMove(item) {
    return this.moving && super.shouldMove(item)
  }
}class MyGraphEditorInputMode extends GraphEditorInputMode {
  private moving = false

  constructor() {
    super()
  }

  shouldMove(item: IModelItem): boolean {
    return this.moving && super.shouldMove(item)
  }
}

Changes to the Collection Types

The collection subsystem that came with yFiles for HTML 1.3 has been simplified and made more consistent with the ECMAScript level 6 collections APIs:

  • On systems that have support for ECMAScript level 6 symbols, the new ECMAScript 6 level for-of construct can be used on all types that implement the IEnumerable<T> interface.

const groupNodes = graph.nodes.filter(graph.isGroupNode, graph)

for (const groupNode of groupNodes) {
  for (const childNode of graph.getChildren(groupNode)) {
    for (const label of childNode.labels) {
      console.log(label.text)
    }
  }
}const groupNodes: IEnumerable<INode> = graph.nodes.filter(graph.isGroupNode, graph)

for (const groupNode of groupNodes) {
  for (const childNode of graph.getChildren(groupNode)) {
    for (const label of childNode.labels) {
      console.log(label.text)
    }
  }
}

  • The "foreach" and other convenience methods on the IEnumerable type now all support index and owner optional parameters for their callbacks and support passing the this context to the callback functions via an optional parameter.

graphComponent.graph.nodes.forEach((n, index) => console.log(`node ${index}: ${n}`))

// directly invoke console.log with node, index, and "graph.nodes" as arguments
graphComponent.graph.nodes.forEach(console.log, console)

  • The member and type names have been adjusted to adhere to the new ES2015 Map and Set classes. Dictionary is now called Map and its accessors and convenience methods use the names and signatures of the corresponding ES2015 types where possible. The names for the list and enumerable implementations have also been adjusted to follow the ES2015 collection type names.

const map = new HashMap()

map.set('key', 'value')
map.set('anotherKey', 'someValue')

console.log(map.keys.some((k) => k.length === 3))
console.log(map.values.reduce((a, v) => a + v))

map.delete('key')
console.log(map.size)const map = new HashMap<string, string>()

map.set('key', 'value')
map.set('anotherKey', 'someValue')

console.log(map.keys.some((k) => k.length === 3))
console.log(map.values.reduce((a, v) => a + v))

map.delete('key')
console.log(map.size)

Changes to Helper Classes and Default Implementations

Many default and convenience implementations of interfaces that did not add anything new to the API other than implementing the existing interface have been refactored to be only available via constants or factory methods on the corresponding interface types. Types that are meant to be subclassed or which add more functionality than is available on the interface are still available.

const inputMode = new GraphEditorInputMode()
inputMode.moveInputMode.hitTestable = IHitTestable.NEVER

new Animator(graphComponent).animate(
  IAnimation.createParallelAnimation(
    List.fromArray([
      new ViewportAnimation(graphComponent, new Rect(20, 30, 40, 50)),
      IAnimation.createNodeAnimation(graph, graph.nodes.first(), new Rect(20, 30, 40, 50), TimeSpan.fromSeconds(2))
    ])
  )
)

Usage of Promises

Where previously in the API one-time callback methods had been used, now Promises are used. This enables a convenient and consistent programming pattern that is compatible with e.g. ECMAScript 2017’s async/await feature. Since Promises are not part of all browser implementations, yet, a simple third-party-code-free shim for Promises is part of the yFiles for HTML package.

try {
  await graphComponent.morphLayout(new OrganicLayout())
  alert('Done!')
} catch (error) {
  alert(`An error occurred during layout ${error}`)
}
const support = new GraphMLSupport()
try {
  await support.saveFile(graphComponent.graph)
  console.log('saved successfully!')
  alert('Done!')
} catch (error) {
  console.log('error during save ' + error)
}

Major Version Change for GraphML

The GraphML produced by yFiles for HTML 2.x has been updated to a new major version that is now consistent across all yFiles family members. Types are separated into distinct XML namespaces. Types that are shared between yFiles family members are in the y namespace. Types that are specific to a product use a product specific namespace (yjs for yFiles for HTML) and use platform typical casing.

Files written using the default configuration of the GraphML file writing mechanism will not be parsed completely correct using an older, unmodified version of yFiles.

In order to provide backwards compatibility with older GraphML files, a demo is provided that shows how to configure the GraphML loading mechanism to also be able to load older GraphML files.

Geometry Support 'Struct' Classes

The yfiles.geometry namespace contains simple value types that describe geometric entities like points, sizes, and rectangles. Previously the API allowed for modifying the values of these primitive types and their Struct-like nature demanded that in order to avoid that other code will modify the values of such a struct that instead a .clone() of the values should be passed. The types in question have now been made immutable so that cloning is no longer required to guarantee that values will not be modified by library or application code. This improves performance but if you are not using JavaScript strict mode, accidental modifications to these values will simply be ignored. We recommend using strict mode in which case you will get an error if you try to accidentally modify struct values.

Previously there were static functions available on those types for arithmetic operations. These have now been refactored as instance methods.

const point = new Point(42, 23)
const rect = new Rect(1, 1, 40, 40)

const newPoint = point.add(new Point(1337, 1337))
const largerRect = rect.add(newPoint)
const longerVector = newPoint.multiply(5)

point.x += 3 // this will now result in an errorconst point = new Point(42, 23)
const rect = new Rect(1, 1, 40, 40)

const newPoint = point.add(new Point(1337, 1337))
const largerRect = rect.add(newPoint)
const longerVector = newPoint.multiply(5)

// @ts-expect-error This results in an error
point.x += 3 // this will now result in an error

Restructured Javascript Modules

For yFiles for HTML 2.x the publicly visible JavaScript AMD and CommonJS modules structure has been simplified and their dependencies have been slightly refactored. See yFiles Library Formats for the new simplified module system and the dependencies.

The new names should make it obvious what functionality you get when you load the module. If unsure, consult the documentation of the types you are interested in. It contains a list of modules that when loaded provides the type. Note that loading one of the modules in the list is enough. It is not required to load all modules in the list.

Modules do not Introduce Globals Anymore

Previously by default loading the yFiles modules with a module loader, the yfiles root namespace got automatically registered with the window or global namespace. This default behavior has changed. If you are loading the yfiles modules using AMD or CommonJS, the modules now all yield the yfiles top-level namespace, except for yfiles\lang which directly yields the yfiles.lang namespace.

require(['yfiles/editor', 'yfiles/lang'], (yfiles, lang) => {
  const graph = new DefaultGraph()
  const demo = lang.module('demo')
})

// here, yfiles is not defined - neither now, nor when the require has resolved the modules
typeof yfiles === 'undefined' // true
typeof lang === 'undefined' // true

Built-in Types are no Longer Modified

yFiles for HTML 1.x added small APIs like toString(), hashCode(), getClass(), equals(), and compareTo() to the prototypes of the built-in JavaScript types Number, String, Boolean, and Object. This is no longer the case. The native type system is now left untouched.

Grouping and Folding

In yFiles for HTML 1.3 the ability to nest nodes into other nodes was an optional feature of the graph implementation that needed to be turned on explicitly and used a separate interface. With yFiles for HTML 2.x this functionality is now an inherent part of the main graph interface and the optional interface has been removed. Since grouping is now always available, the input mode implementations provide switches that prevent the user from interactively using this feature if this is not desired in an application.

// grouping is available directly from the graph interface
const groupNode = graph.createGroupNode()

const normalNode = graph.createNode()
const childNode = graph.createNode({ parent: groupNode })
graph.setParent(normalNode, groupNode)
console.log(graph.getChildren(groupNode).size)

// more advanced queries are available via helper type IGroupingSupport
console.log(graph.groupingSupport.isDescendant(normalNode, groupNode))

The more elaborate folding feature still uses separate interfaces, since more than one graph instance can be involved for this use case.

ECMAScript Level 6

yFiles for HTML 2.x is designed to work seamlessly with ECMAScript Levels 6 and 7, however the core library only requires an ECMAScript Level 5 runtime to work. Many of the demos have been adjusted to use ECMAScript Level 6 features and thus will not work out of the box in older browsers that do not have native support for the newer features in JavaScript. These demos work in all evergreen browsers, but a transpiler should be used to make those demos work in older browser implementations. Most notably this affects all current versions of Internet Explorer. Edge can run the unmodified demo code.

Layout and Graph Analysis

yFiles for HTML 2.x offers a new and more convenient way to supply layout algorithms with configurations on a per item basis. Where previously the recommended approach was to use the mapper registry to register mappings from items to supplemental layout data, there are now convenience classes available that make declaring and applying supplemental layout data to graph items in a type-safe and more discoverable way. This is a non-breaking change, since the old mechanism is still in place and may be used for custom layouts and more advanced layout customizations.

const data = new HierarchicLayoutData({
  sourcePortConstraints: (edge) =>
    edge.sourceNode.tag !== 'center' ? PortConstraint.create(PortSide.NORTH, true) : null,
  partitionGridData: new PartitionGridData({
    grid: new PartitionGrid(2, 2),
    cellIds: (node, grid) => grid.createCellId(1, 1)
  })
})

await graphComponent.morphLayout({
  layout: new HierarchicLayout(),
  layoutData: data
})
const data = new HierarchicLayoutData({
  sourcePortConstraints: (edge: IEdge) =>
    edge.sourceNode!.tag !== 'center' ? PortConstraint.create(PortSide.NORTH, true) : null,
  partitionGridData: new PartitionGridData({
    grid: new PartitionGrid(2, 2),
    cellIds: (node: INode, grid: PartitionGrid): PartitionCellId => grid.createCellId(1, 1)
  })
})

await graphComponent.morphLayout({
  layout: new HierarchicLayout(),
  layoutData: data
})

Detailed Changes

General

  • The naming of classes, members, and parameters has been reviewed and is now both more consistent with other JavaScript APIs and more intuitive.
  • The return type of several methods has been changed from IEnumerator<T> to IEnumerable<T>. All implementations of IEnumerable are JavaScript Iterables and thus can be used in for…​of loops etc.
  • Replaced all usages of reference parameters with actual return values. Most prominent example of this change are the various #getTangent methods in IPathGeometry and GeneralPath that now return a Tangent object.
  • All methods that take a parameter of type ICanvasContext, IRenderContext, IInputModeContext, IParseContext, IWriteContext, SnapContext, GraphSnapContext, or LabelSnapContext now have that parameter as their first parameter.
  • Removed all types with name 'Extensions' since these duplicated methods that are available on the corresponding types, too. This includes: OrientedRectangleExtensions, PointExtensions, RectangleExtensions, SizeExtensions, FoldingViewExtensions, GeomExtensions, GraphDecoratorExtensions, GraphExtensions, GroupedGraphExtensions, MapperRegistryExtensions, StripeExtensions, LookupExtensions, TableExtensions, ParseContextExtensions, WriteContextExtensions, RenderContextExtensions, RenderContextExtensions and XmlWriterExtensions.
  • The Developer’s Guide has been completely revised. Now it consists of two parts: The first part covers the basics of yFiles for HTML, while the second part describes in detail how the behavior of the library can be adapted to the customer’s requirements.

Namespace Structure

  • Classes of the viewer part have been reorganized into a simpler namespace structure.
    • yfiles.graph contains types relate to the graph structure, including label models and port location models.
    • yfiles.view was renamed from yfiles.canvas and contains types related to the GraphComponent and CanvasComponent, and to the visualization in general.
    • yfiles.styles was renamed from yfiles.drawing and contains the style implementations.
    • yfiles.input contains the types related to input modes.
  • Collections and geometry types remain in yfiles.collections and yfiles.geometry, respectively.
  • The namespaces yfiles.model, yfiles.objectcollections, yfiles.support, and yfiles.system have been dissolved. A lot of their types were obsolete and have been removed, the remaining have been moved to more meaningful namespaces. Details are described below.
  • Layout and analysis types are still in yfiles.layout, yfiles.algorithms, and the namespaces that correspond to a specific layout style.

Factory Methods Instead of Default Implementations

  • ICanvasContext: factory methods replace the removed class CanvasContext
  • IInputModeContext: factory methods replace the removed class SimpleInputModeContext
  • ILookup, IContextLookup and IContextLookupChainLink: factory methods were moved from the removed class Lookups
  • IContextLookupChainLink: factory methods replace the removed properties HidingLookupChainLink, FactoryLookupChainLink and AddingLookupChainLink.
  • IEnumerable: factory methods replace the removed classes EmptyEnumerable, CompositeEnumerable and CompositeEnumerator
  • IListEnumerable: factory methods replace the removed classes EmptyListEnumerable, ListEnumerable and ListEnumerableExtensions
  • IEventRecognizer: factory methods replace the removed classes EventRecognizers, EventRecognizerExtensions, and EventRecognizerCallback.
  • IAnimation: factory methods replace the removed classes EasedAnimation, ParallelAnimation, GeneralPathAnimation, LayoutMorpher, LayoutMorpherWrapper, EdgeAnimation, LabelAnimation, NodeAnimation, and PortAnimation
  • IPortCandidateProvider: factory methods replace all existing implementations except AbstractPortCandidateProvider
  • IEdgeReconnectionPortCandidateProvider: factory methods replace all existing implementations.

Moved Static Members to Interfaces

  • ICommand: got constants of the removed classes GraphCommands, ApplicationCommands, ComponentCommands and NavigationCommands
  • IArrow: got constants from the type Arrow.
  • IHitTestable/IMarqueeTestable/IVisibilityTest: got constants from removed classes HitTestable, MarqueeTestable and VisibilityTest
  • ICanvasObjectDescriptor: got constants of the removed class CanvasObjectDescriptor.
  • IMapper: got factory methods of removed class Mappers.
  • IBoundsProvider: got constants of removed class BoundsProvider.
  • Class GraphItemTypes got constants of removed class GraphItemType.
  • Class Fill got constants of removed class Brushes.
  • Class Stroke got constants of removed class Pens.
  • Class DashStyle got constants of removed class DashStyles.

Model

IGraph

  • Support for grouped graphs has been simplified to a large extent:
    • IGraph now supports grouping by default. The #groupingSupported property has been removed from DefaultGraph. Grouping is now always enabled for graphs.
    • The new property #allowGroupingOperations on GraphEditorInputMode allows for switching interactive grouping operations on or off. Grouping operations are disabled by default and have to be enabled explicitly if the input mode should support them.
    • The grouping support interfaces IGroupedGraph and IHierarchy<T> have been removed and folded with IGraph.
    • IHierarchy<T>'s Root property is no longer available. The root of a grouping hierarchy is now represented by null.
  • Overhaul of IGraph’s #createNode, #createEdge, #addLabel, #addPort: Ambiguous overloads were removed, missing overloads were added and parameters were ordered to be consistent throughout all overloads.
  • The names of the property setter methods have been changed so that it is easier to find the model item’s property they affect. For instance, #setNodeBounds is now #setNodeLayout, as the property it affects is INode#layout.
  • IGraph’s #nodes, #edges, #labels, and #ports properties have been changed from ICollectionModel to IListEnumerable. To be notified of created or removed items, the corresponding IGraph events should be used instead.
  • The properties #nodeLabels and #edgeLabels on IGraph have been replaced by non-abstract default implementations that delegate to the merged #labels property.
  • The properties #collectionModel and #bends have been removed.
  • The classes BendList and ListLabelCollection have been removed. Use ListEnumerable instead.
  • IGraph now provides events for property changes on model items, e.g. #NodeStyleChanged, #NodeLayoutChanged, etc. Those events replace the dedicated change reporters available previously (e.g. INodeBoundsChangeReporter, ILabelTextChangeReporter, etc.) which have been removed.
  • The signatures of event handlers throughout the IGraph API have been made consistent using properly typed EventArgs subtypes. Exceptions are a few events that are raised very often which retain an argument list to improve performance.
  • The methods isLeaf/setLeaf and related properties and events have been replaced by isGroupNode/setIsGroupNode which have the exact opposite meaning from the old ones.
  • The signature of IGraph#addBend has changed. The index parameter has been moved to the end and made optional.
  • The IGraphStructure interface and its SimpleGraphStructure implementation have been removed, as well as DefaultGraph’s constructor that accepted an IGraphStructure.
  • IGraph now extends the ITagOwner interface. Thus graphs now have a #tag property.

DefaultGraph

  • DefaultGraph now raises removal events for labels, ports, and bends which are implicitly removed when their owner is removed.
  • Various protected factory methods on DefaultGraph have been removed: #createNodeDefaults, #createEdgeDefaults and #createMapperRegistry, amongst others.
  • The method #getBounds has been removed from DefaultGraph.
  • The property #usePortCandidateProviders has been removed from both DefaultGraph and GraphSettings. Creating an edge using port candidate providers has to be done by manually querying the provider and calling #createEdge(IPort, IPort).

Folding

  • The method #isInitiallyExpanded has been removed from IFoldedGraph. The methods #isInitiallyExpanded, #setInitiallyExpanded, and the property #defaultExpandedPredicate have been removed from FoldingManager.
  • The #expand, #collapse and #isExpanded methods on IFoldingView (previously IFoldedGraph) now also work with nodes that belong to the master graph instead of the view graph. Thus the collapsed/expanded state can be set or queried for items that are currently not in the view graph.
  • The interfaces IChangeDummyNodeAppearanceCallback, IChangeDummyEdgeAppearanceCallback, and IChangeLabeledItemAppearanceCallback as well as the FoldingManager#getChangeDummyAppearanceCallback methods have been removed. The view state properties can now directly be changed on the view state implementations returned by FoldingManager#getFolderNodeState and FoldingManager#getFoldingEdgeState, respectively.

Labels

  • The #layout property of ILabel has been converted to a default property implementation.
  • The order of the parameters of ILabelModel#getGeometry has been changed to ILabelModel#getGeometry(ILabel, ILabelModelParameter).
  • FreeNodeLabelModel#createNodeCenterAnchored and FreeNodeLabelModel#createNodeLayoutAnchored have been removed.
  • FreeNodeLabelModel#createDefaultParameter now uses the label’s center as its anchor point.
  • The new edge label models EdgeSegmentLabelModel and EdgePathLabelModel have been added. EdgeSegmentLabelModel allows to create parameters for a segment index and segment ratio while EdgePathLabelModel creates parameters using a ratio of the edge path.
    • The label models RotatingEdgeLabelModel, SliderEdgeLabelModel, SideSliderEdgeLabelModel, RotatedSliderEdgeLabelModel and RotatedSideSliderEdgeLabelModel have been removed.
    • The label model parameter of the edge label defaults now uses the EdgeSegmentLabelModel.

Ports

  • Refactored property IPort#location to become a default implementation since it was only a convenience method to access the location from the IPortLocationModelParameter. To retrieve a live view of the location of a port, use the new default property IPort#dynamicLocation. To retrieve a simple snapshot of the current location instead, use IPort#getLocation.
  • NodeScaledPortLocationModel has been replaced by FreeNodePortLocationModel that allows to specify the port location by a ratio of the node layout’s size and an additional offset.
  • AnchoredPortLocationModel has been removed.

Table

  • ITable:
    • The signature of #createRow and #createColumn has changed. The index parameter has been moved to the end and made optional.
    • Events #StripeChanged and #StripeRemoved use StripeEventArgs now. The corresponding event raiser methods have been changed accordingly.
    • Event #LabelRemoved uses LabelEventArgs now.
    • added default implementations methods: #findColumn, #findRow, #getCellBounds
  • Class Table:
    • the table’s lookup decorator can now decorate stripe labels, too.
    • removed methods: #createDefaultColumnStyle, #createDefaultColumnInsets, #createDefaultColumnLabelStyle, #createdDefaultColumnLabelModelParameter, #createColumnLabelDefaults, #createDefaultRowStyle, #createDefaultRowInsets, #createDefaultRowLabelStyle, #createdDefaultRowLabelModelParameter, #createRowLabelDefaults, #removeUndoSupport, some overloads of #createRow/#createColumn, some overloads of #addLabel
    • Added properties #DEFAULT_STRIPE_LOOKUP, #DEFAULT_COLUMN_LOOKUP and #DEFAULT_ROW_LOOKUP that replace the removed classes with the same same.
  • TableExtensions: method #getElementsToMove has been removed
  • Property IStripeSelection#selectedStripes has been removed. Use the individual properties for #selectedRows and #selectedColumns instead
  • StripeSelection: the surplus overloads of #isSelected and #setSelected taking an IRow or IColumn have been removed.
  • The static helper method #placeNodeInCell has been added to ITable to easily move a node into a specific table cell.

Undo Support

  • Convenience default methods to enable/disable Undo have been added to IGraph.
  • Setting the #tag property on model items and the graph now works with Undo.
  • Undo operations for the removal of graph elements now keep the proper item order. This improves the consistency especially for layouts between undo operations.
  • Overloads of the IGraph#beginEdit default method that work with IMementoSupport (either via ILookup or an IMementoSupportProvider) have been added.
  • The overload of the IGraph#beginEdit default method that accepted an IEnumerable of IModelItems has been removed.
  • IUndoSupport, MementoUndoUnit, MementoUndoableEdit, and MementoStateStruct have been removed.
  • IUndoUnit: the methods #canUndo and #canRedo have been removed.
  • The methods #undoImpl and #redoImpl on AbstractUndoUnit have been removed. Implementations should use #undo and #redo from the IUndoUnit interface instead.
  • The properties #undoText and #redoText on UndoEngine have been removed.
  • The interface IGraphUndoUnitSupport has been removed. Its methods #create…​UndoUnit have been moved to DefaultGraph as overridable methods. Developers who have created a custom implementation have to derive from DefaultGraph and override the corresponding method(s).

Geometry

Namespace yfiles.geometry was simplified and cleaned up.

  • The basic geometry types PointD, SizeD, RectD and InsetsD have been made immutable and the "D" suffix has been removed.
  • The classes ImmutablePoint, ImmutableSize, ImmutableRectangle and ImmutableOrientedRectangle have been removed. The immutable types Point, Size and Rect as well as the immutable instance provided by the new static method OrientedRectangle#createImmutable can be used instead.
  • The interfaces IPointSetter and ISizeSetter have been removed. Instead their prior sub interfaces IMutablePoint and IMutableSize are used.
  • The IReshapeable interface has been removed. The various overloads of the #reshape method have been implemented as default methods on IMutableRectangle instead.
  • IMovable has been removed as well. Instead an IPositionHandler can be used.
  • PointD#fromPoint, SizeD#fromSize and RectD#fromRectangle have been removed and replaced by the default methods IPoint#toPoint, ISize#toSize, and IRectangle#toRect.
  • Various other geometry-related infrequently used or duplicate classes and interfaces have been removed.
  • The static fields ImmutableSize#UNBOUND, ImmutableSize#EMPTY and ImmutableSize#ZERO have been added.

Controls and Components

  • Renamed GraphControl, GraphOverviewControl, and CanvasControl to GraphComponent, GraphOverviewComponent, and CanvasComponent, respectively.
  • Removed base class Control and its methods and events that duplicated plain JavaScript events (MouseEventArgs, TouchEventArgs, KeyEventArgs). The yFiles-specific events Mouse2DEventArgs, Touch2DEventArgs, and CompoundKeyEventArgs are still present and have been renamed to MouseEventArgs, TouchEventArgs, and KeyEventArgs.
  • Replaced TextBox with plain HTML5 TextArea. Made ScrollBar internal. It was never intended for usages outside of Graph/CanvasComponent.
  • Moved load and save features from GraphComponent to GraphMLSupport.

Members of GraphComponent

  • The ContentRect will now also be updated when creating edges, adding, editing or moving labels or deleting all graph item types.
  • The CUT, COPY and PASTE commands are no longer handled and the respective methods have been removed as well. COPY command bindings are still supplied by GraphViewerInputMode and GraphEditorInputMode. CUT and PASTE command bindings are still supplied by GraphEditorInputMode.
  • The UNDO and REDO commands are no longer handled and the respective methods have been removed as well. UNDO and REDO command bindings are still supplied by GraphEditorInputMode. Furthermore, the respective methods can still be called on the UndoEngine directly.
  • Property #UndoabilityEnabled has been removed. Undo and Redo commands can be enabled on the GraphEditorInputMode.
  • Property #ClipboardEnabled has been removed. Clipboard commands can be enabled on the GraphEditorInputMode.
  • Method #getUndoEngine has been removed. The current UndoEngine can be retrieved from the GraphComponent#Graph.
  • Event #SelectionChanged has been removed.
  • The new property #LastEventLocation always contains the location of the last mouse event.
  • The property #MouseWheelBehavior taking a value of type MouseWheelBehaviors replaces the previous property #AutoMouseWheelZoomEnabled.
  • The ObjectProperty #fitContentViewMarginsProperty has been added that allows to observe when the property #FitContentViewMargins has been changed.
  • The methods #add, #addCreator, #addGroup and #addGroupToGroup have been removed as the new methods #addChild and #addGroup of ICanvasObjectGroup provide a more intuitive way to add child elements to e.g. the GraphComponent#getBackgroundGroup.
  • The property #InputModes has been removed. Developers who want to install multiple input modes on a CanvasComponent have to set a MultiplexingInputMode as CanvasComponent#InputMode and add their input modes to that mode.
  • Method #collectCanvasObjects has been removed

Visualization

Styles

  • Renamed SimpleAbstractNode/Edge/Port/LabelStyle to Node/Edge/Port/LabelStyleBase. In addition, the type parameter of has been removed from all these types.
  • Removed SimplePortStyle. Instead, use NodeStylePortStyleAdapter with ShapeNodeStyle.
  • Renamed SimpleLabelStyle to DefaultLabelStyle.
  • Renamed Typeface to Font and simplified the API of TextRenderSupport.
  • Added the interface IStripeStyle for styles of IColumns and IRows. With NodeStyleStripeStyleAdapter, you can still use node styles as styles for columns and rows.
  • Removed all Visuals except Visual, SvgVisual (was DefaultVisual), HtmlCanvasVisual (RenderVisual), and SvgVisualGroup (CanvasContainer). All of them can be replaced with SvgVisual and corresponding SVG elements.
  • The style and style renderer hierarchies have been flattened
    • Removed all sub-interfaces of INodeStyle, IEdgeStyle, ILabelStyle, and IPortStyle.
    • Removed classes AbstractEdgeStyle, AbstractStyleRenderer, AbstractNodeStyleRenderer, AbstractEdgeStyleRenderer, AbstractLabelStyleRenderer, AbstractShapedNodeStyleRenderer, AbstractShapedLabelStyleRenderer, VoidVisualStyle, and VoidStyleRenderer
    • Merged types AbstractTableNodeStyle and DynamicTableNodeStyle into TableNodeStyle.
  • Removed superfluous interfaces IUserTagProvider and ITableProvider, and all implementations.
  • Removed superfluous constructors from all style implementations.
  • All IStyleRenderer implementations: the accessibility of the #Style, #Layout, and #Item properties has been reduced to protected. In addition, the latter has been renamed to #Node, #Label, #Edge, or #Port respectively.
  • Various changes to IModelItemInstaller and related interfaces and classes. Styles no longer implement IModelItemInstaller, simplifying certain custom style implementations.

Various Visualization Changes

  • Customizing the visualization of handles etc. via data templating has been refactored. The new interface IVisualTemplate is similar to IVisualCreator and replaces the types IDataTemplate, DataTemplate, and the related visuals.
  • The protected factory methods that supplied the initial value for GraphModelManager’s Installer properties (#EdgeStyleInstaller, #NodeStyleInstaller, etc.) have been removed.
  • GraphModelManager#invalidate has been removed.
  • Added a mechanism to support disposing and caching Visuals which are created by IVisualCreator#createVisual. Add methods #setDisposeCallback, #childVisualRemoved, and #registerForChildrenIfNecessary to IRenderContext.
  • The method IRenderContext#canvas has been pulled up to ICanvasContext and renamed to #canvasComponent.
  • IRenderContext: the property #Transform has been removed
  • Removed class RenderContext. Use ContextConfigurator#createRenderContext instead to retrieve an instance of IRenderContext.
  • DefaultEdgePathCropper now uses the new method #handleEmptyPath if cropping the edge would result in an empty path. Per default this method only crops at the ports.
  • DefaultEdgeIntersectionCalculator: a callback method #getNodeGeometry has been added.
  • The property #CanvasObjectGroupProviderCallback on ModelManager has been replaced with the virtual method #getCanvasObjectGroup. The property #CanvasObjectGroupProviderCallback on ItemModelManager has been replaced with the property #CanvasObjectGroup and the virtual method #getCanvasObjectGroup; the default implementation just defers to the property, just like #getDescriptor.
  • IGroupAction as well as ICanvasObjectGroup#getGroupAction have been removed as they had hardly any use.
  • The interface ICanvasGroupProvider and the delegate CanvasObjectGroupProviderCallback have been removed. Accessing the individual CanvasObjectGroups can be done via the properties of CanvasComponent instead.
  • Removed ICanvasObjectTreeEventSource and the corresponding classes CanvasObjectAddEventArgs, CanvasObjectRemoveEventArgs, CanvasObjectMoveEventArgs, and CanvasObjectInvalidateEventArgs.

Input

General Input Mode refactorings

  • The type hierarchy for input modes has been simplified considerably:
    • All input modes except OverviewInputMode, GraphViewerInputMode, and GraphEditorInputMode now directly implement IInputMode without any abstract base classes in between.
    • IConcurrentInputMode has been removed and merged into IInputMode.
      • The #enabled property on the interface has been removed. It is still present on all concrete implementations.
      • The concurrencyController property has been removed. Instead, a parameter of type ConcurrencyController has been added to the IInputMode#install method.
    • All abstract input mode base classes except AbstractInputMode have been removed. AbstractConcurrentInputMode has been merged into AbstractInputMode.
    • AbstractInputMode: #requestMouse, #requestTouch, #releaseMouse, and #releaseTouch have been combined into #requestPointer and #releasePointer
  • Input mutex handling has been refactored considerably:
    • IInputMode’s concurrencyController property has been removed. Input modes now get a ConcurrencyController as parameter of their #install method.
    • The ConcurrencyController has been refactored and is now only responsible for a single input mode. Its #active property indicates if the input mode currently has or may request the mutex.
    • The class InputMutex has been removed.
    • The #preferredCursor property has been moved from IInputMode to ConcurrencyController.
    • The input mutex should be requested and released using the according methods on ConcurrencyController. Most input modes don’t provide the methods #hasMutex, #canRequestMutex, #requestMutex and #releaseMutex anymore.
    • The #enabled property of IInputModes is not set to false anymore if another input mode acquires the mutex. Instead their ConcurrencyController is deactivated. This provides a clear separation between suppressing input modes (while another mode holds the mutex) and explicitly disabling a mode from code (via the #enabled property).
    • As a consequence most input modes don’t provide the EnabledChanged event and the #onEnabled and #onDisabled protected methods anymore, but #onConcurrencyControllerActivated and #onConcurrencyControllerDeactivated instead.
  • IInputMode has a new property #priority which defines the installation priority of the input mode. Previously those were available as properties on GraphViewerInputMode, GraphEditorInputMode, and TableEditorInputMode. Those have been removed.
  • IInputMode’s #stop method has been renamed to tryStop to make it more obvious that an implementation might return false to indicate that it did not actually stop.
  • All input modes no longer raise Stopped and Canceled events. Developers who want to get notified when an input mode gets stopped or canceled have to override the #onStopped and #onCanceled methods. Also, the events Initializing and Initialized no longer exist. Input modes that need to perform one-time initialization on first #install can keep track of that themselves.
  • MultiplexingInputMode: the #addConcurrent methods as well as the #add method which takes an additional priority parameter have been removed. There is only one #add method left, which takes an input mode as its only parameter. Priority is determined by the input mode’s #priority property. Whether an input mode runs exclusive or always active alongside other input modes is determined by the input mode’s ConcurrencyController which has an #exclusive property controlling that. This property is also available for all default IInputMode implementations.
  • MultiplexingInputMode is now aware of changes to the priority of already installed input modes and will update the installation order accordingly when an input mode’s priority is changed.
  • IInputModes in general
    • the setter for #graph and #graphSelection properties, if present, and its associated #set* methods have been removed. Both are now always retrieved from the input mode context dynamically.
    • the read-only property #inputModeContext has been introduced to expose the IInputModeContext the mode is installed in.
    • Many input modes now no longer have protected methods for state machine transitions. Instead those methods are mostly parameterless now.

GraphEditorInputMode and GraphViewerInputMode

  • GraphViewerInputMode and GraphEditorInputMode have been made more similar regarding customization in the capabilities they both provide:
    • GraphViewerInputMode now supports the same click and selection behavior as GraphEditorInputMode. This includes detail selection (Shift+Click) and cyclic selection (Alt+Click) as well as finer control over behavior like the #clickSelectableItems property and the #shouldClickSelect method.
    • The methods #click and #doubleClick now take an IModelItem and ClickEventArgs as arguments and have no return value. Instead of returning a boolean, the #handled property on the ClickEventArgs should be set.
    • Their #clickInputMode instances now delivers both left and right clicks at the same time.
    • The default click actions that change the selection and create new nodes are only triggered on left mouse clicks now.
    • An explicit hit test order for double clicks is provided that can be changed through the #doubleClickHitTestOrder property. By default, this hit test order prefers labels over other graph elements.
    • GraphViewerInputMode now also has the #availableCommands property, already known from GraphEditorInputMode or NavigationInputMode.
    • Several child input mode priorities in GraphViewerInputMode have been changed and most of them now have the same priorities as in GraphEditorInputMode
    • The new #CanvasClicked event reports clicks on an empty canvas location.
    • The new property #selectablePredicate allows finer control over what particular items should be selectable without the need to create a custom subclass.
    • The new method #createSelectionEventArgs creates SelectionEventArgs using the #graphSelection.
    • The events MultiSelectionStarted and MultiSelectionFinished now use SelectionEventArgs<IModelItem>.
    • By default, graph items styled with a void style (VoidNodeStyle, VoidEdgeStyle, VoidLabelStyle, and VoidPortStyle) are not selected or focused anymore. The new property #voidStylesIgnored specifies whether this feature is enabled.
    • GraphViewerInputMode now has improved support for marquee selection. Marquee selection is no longer turned on or off via #marqueeSelectableItems but instead directly on the MarqueeSelectionInputMode. The recognizer for marquee selection is Shift+Drag and the child input mode priorities have been adjusted accordingly so that marquee selection and viewport movement can co-exist. The child input mode still defaults to being disabled, though.
    • GraphViewerInputMode now also has a KeyboardInputMode.
    • GraphViewerInputMode now allows copying items (including the convenience method) and handles the command appropriately.
  • Improved functionality of GraphEditorInputMode
    • Changing the #showHandleItems property will now immediately update the currently visible handles.
    • The new property #deletablePredicate allows finer control over what particular items should be deletable without the need to create a custom subclass.
    • The new events #LabelAdding and #LabelEditing were added. Those allow fine-grained control over adding or editing labels and tie into the existing functionality provided by IEditLabelHelper.
  • Clean-up of the old GraphEditorInputMode API
    • The type of the property #orthogonalBendRemoval has been changed from boolean to OrthogonalEdgeEditingPolicy.
    • The events DeletingSelection and DeletedSelection now use SelectionEventArgs<IModelItem>.
    • The constructor that take additional IGraph and IGraphSelection arguments have been removed, as well as the protected methods #setGraph, #setGraphComponent, #onGraphChanged and the protected setter for the #GraphSelection property. Instead, the IGraph instance is now always taken from the #InputModeContext and can’t be changed after the mode is installed.
    • #createDefaultLabelConfiguration has been removed
    • #marqueeSelect<T>(RectD,IEnumerable<T>) has been removed.
    • #SelectionModel has been removed. Instead the #GraphSelection property is used.
    • #CollectionModel has been removed. Instead the model items of the #Graph property are used.
    • #GraphInputModeController has been removed.
    • The protected event handlers for ClickInputMode’s Clicked and DoubleClicked events have been removed.
    • #findItem has been removed. An additional overload of #findItems without the context parameter has been added. To replicate the previous behavior of #findItem, #findItems can be called and the first element taken from the resulting enumeration.
    • #shouldBeMovableForMoveInputMode has been removed.
  • Improved GraphViewerInputMode API:
    • Added support for the COPY command.
    • Added support for multi-selection via Ctrl+Click and marquee selection. The latter is disabled by default.
    • The click hit test order can now be configured by property #clickHitTestOrder.
    • By default, clipboard commands are now disabled. This can be controlled with the new property #allowClipboardOperations.
    • The ItemSelected event has been removed.
    • #ClipboardCommandsEnabled has been removed.

CreateEdgeInputMode

  • CreateEdgeInputMode was refactored and streamlined:
    • Orthogonal edge creation will be automatically enabled if orthogonal edge editing is enabled on the containing GraphEditorInputMode.
    • Property #connectToCandidatesOnly was removed. Now edge creation always uses port candidates.
    • The creation callbacks #nodeBasedEdgeCreationCallback and #portBasedEdgeCreationCallback have been replaced by the new #edgeCreator which is port-based.
    • The methods #getSourcePortOwner, #getTargetPortOwner, #getSourceNode and #getTargetNode have been replaced by #getSource and #getTarget.
    • The properties #sourcePortCandidate and #targetPortCandidate now are read-write.
    • The methods #determineEdgeStyle, #assignSourcePortPosition, #assignEdgeStyle as well as the property #edgeStyle have been removed. Instead the new #edgeDefaults property can be used to customize the new edge.
    • Property #useHitNodeTargetCandidatesOnly was replaced by the new #useHitItemsCandidatesOnly property.
    • The type of the property #orthogonalEdgeCreation has been changed from boolean to OrthogonalEdgeEditingPolicy.
    • The new property #dummyEdgeGraph is used to create the dummy edge that visualizes the edge during creation.
    • The preview edge which is displayed during edge creation now shows the edge as it will be created, i.e. the preview edge has the same style, port visualization, and labels as the created edge will have.
    • The property #snapToTargetCandidateOwner has been removed. The preview edge now is always being cropped at the candidate owner’s borders.
    • A new property #cancelGestureOnInvalidTarget has been added that makes it possible to cancel the gesture immediately if ended on an invalid target.
    • #edgeCreator callback now has a templateEdge parameter where all data for edge creation can be retrieved from. The source and target IPort parameters have been changed to IPortCandidates.
    • #assignBends has been removed and its functionality folded into the default #edgeCreator implementation.
    • The following methods have been removed: #isPortCandidateResolutionEnabled, #isValidEnd, #isValidBegin, #isCancelGesture, #isBendCreationEnforced, #isValidBend, #isSourceNodeDraggingFinished, #isRemoveBendEvent. Instead, use the corresponding #*EventRecognizer properties to customize the behavior.
    • The following methods and properties have been removed: #createBend(PointD), #startCreateEdge, #onTargetLocationChanged, #getNodes, #nodeComparer, #portOwnerComparer.

Other Input Modes

  • AbstractContextMenuInputMode: Support for different context menu trigger events has been added. Currently only mouse (right-click) and keyboard (application / context menu key) are distinguished, more may be added in the future.
  • ClickInputMode: The property #validClickHitCursor has been added. This cursor is used when hovering over a valid hit region.
  • ClickInputMode: Added new method #preventNextDoubleClick that can be used in event handlers for single clicks to prevent that this click can become part of a double click event.
  • CreateBendInputMode: The property #cancelEventRecognizer has been removed.
  • HandleInputMode: The property #active has been removed. The mode can be manually deactivated using the #enabled property instead.
  • HandleInputMode: The method #arm now has a handle parameter for the handle that is under the mouse cursor.
  • NodeDropInputMode: Removed callback #nodeCreator, event #nodeCreated and method #getDraggedNode. Used callback #itemCreator, event #ItemCreated and property #DraggedItem from superclass ItemDropInputMode instead.
  • OverviewInputMode now extends MultiplexingInputMode.
  • OverviewInputMode can be customized more easily. Minor modes can be replaced and adjusted, as well as the list of available default command bindings can be modified.
  • OverviewInputMode: The new property #margins specifies margins for the visible area of the bound GraphOverviewComponent. The new protected method #updateVisibleArea provides further means for customizing the visible area.
  • MarqueeSelectionInputMode: The events DragStarting, DragStarted, Dragging, Dragged, DragFinishing, DragFinished, DragCanceling and DragCanceled now use MarqueeSelectionEventArgs that provide the current selection rectangle.
  • MarqueeSelectionInputMode: The event MarqueeSelected has been removed. The DragFinished event can be used instead.
  • MarqueeSelectionInputMode: Property #lastModifierState has been removed.
  • MoveInputMode now provides a #QueryPositionHandler event that queries an IPositionHandler each time a drag is started.
  • MoveViewportInputMode: Mouse cursor handling is now also done by protected methods #arm and #disarm, similar to other input modes.
  • MultiplexingInputMode: The #childController property and #createChildConcurrencyController method have been removed.
  • TableEditorInputMode: The new events #LabelAdding and #LabelEditing allow fine-grained control over adding or editing labels and tie into the existing functionality provided by IEditLabelHelper.
  • TableEditorInputMode: The events DeletingSelection and DeletedSelection now use SelectionEventArgs<IStripe>.
  • TableEditorInputMode: now contains the property #allowMixedSelection which has been moved from the removed class CompositeStripeSelection.
  • WaitInputMode#getMultiplexingInputMode has been removed.
  • TextEditorInputMode: The events EditingStarted, EditingCanceled and TextEdited now use TextEventArgs.
  • TextEditorInputMode: The properties #stopRecognizer, #cancelRecognizer and #lineBreakRecognizer have been added which allow for easy customization of the key gestures used to add new line breaks and to cancel or stop the text editing.

Label Editing

  • IEditLabelHelper was refactored:
    • #addLabel and #editLabel were replaced by the methods #onLabelAdding and #onLabelEditing which take the new LabelEditingEventArgs as only argument.
    • The method IEditLabelHelper#configureTextEditorInputMode has been removed. It has been replaced by the property LabelEditingEventArgs#textEditorInputModeConfigurator.
    • The customizations possible from IEditLabelHelper are the same as those from the LabelAdding and LabelEditing events on GraphEditorInputMode and TableEditorInputMode. IEditLabelHelper is conceptually used as another event handler for those events.
    • The property #owner of the implementing class EditLabelHelper has been removed, along with the respective constructor. The label owner can usually be queried from the LabelEditingEventArgs. Custom subclasses can of course still opt to store the item they were created for and use that field.
  • If an IEditLabelHelper implementation is present in an ILabeledItem’s lookup, its #addLabel method is called to determine whether a label may be added and provide a suitable label instance. Additionally, the predicate method GraphEditorInputMode#shouldLabelBeAdded always has to return true, whether edit helpers are present or not. If the new label should be edited interactively after it’s creation (the default behavior), it also must be editable, following the rules above. Therefore an IEditLabelHelper implementation usually should allow editing of label instances that it has created itself in #onLabelAdding.
  • The current label visual can be hidden while the text editor is shown to reduce visual clutter. This feature is enabled by default and can be controlled through the property GraphEditorInputMode#hidingLabelDuringEditing.

Snapping

  • SnapContext:
    • A boolean parameter snappingDisabled has been added to the methods #handleMove and #dragFinished. This parameter has to be set to true to handle moves or finish a drag when snapping is temporarily disabled. This replaces the call to SnapContext#disableSnapping.
    • The events Initializing, Initialized and CleanedUp as well as associated methods now use InputModeEventArgs.
    • #VOID_INSTANCE has been removed.
  • GraphSnapContext:
    • The return type of #getMovementInfos has been changed to IListEnumerable<MovementInfo> and the classes NodeMovementInfo, PortMovementInfo, BendMovementInfo and EdgeEndMovementInfo have been removed.
    • The info parameter’s type of #addEdgeEndToBeMoved has been changed to the more general MovementInfo. A boolean parameter atSource has been added.
    • The methods #addSameWidthEntries and #addSameHeightEntries now return an IListEnumerable<Rect> containing the rectangles whose widths respectively heights are closest to the given size. The parameters resultingSize and rects have been removed.
  • IEdgeSnapResultProvider
    • The methods #initializeSnapping and #cleanupSnapping have been removed.
    • The info parameter’s type of #CollectSnapResults has been changed to IListEnumerable<MovementInfo>.
  • SnapResult now has more factory methods. The class SnapLineSnapResult has been replaced by a factory method as well.
  • The Classes SnapLineContainer, SingleLineSnapLineContainer, EdgeSegmentSnapLineContainer, FixedDistanceSnapLineContainer, InBetweenSnapLineContainer have been removed.

Clipboard

  • The GraphClipboard#clipboardContext property has been removed.
  • The #copy methods in GraphCopier now have a new Point offset parameter that shifts nodes and bends by a given amount upon copying them.
  • The signature of IClipboardIdProvider#getId has changed. The context parameter has been moved to the front.

KeyboardInputMode

  • KeyboardInputMode has been drastically simplified along with all helper types and infrastructure around commands:
    • Classes RoutedCommand, RoutedUICommand, and CommandManager have been removed, along with CanExecuteRoutedEventArgs and ExecutedRoutedEventArgs
    • The ICommand interface has added the target parameter to the execute and canExecute methods
    • ICommand now holds all available predefined commands as constants (with the "_COMMAND" suffix removed). It also contains a factory method that allows for creating an ICommand for use with KeyboardInputMode and the #invalidateRequerySuggested method from CommandManager.
    • The #commandBindings and #inputBindings properties of CanvasComponent have been removed and functionality is now available via KeyboardInputMode, exclusively.
    • KeyBoardInputMode now offers two ways to create between for keys presses and generic key gestures to commands and a single method to provide custom execution logic for a given command. All of these methods (#addCommandBinding, #addKeyBinding, and #addRecognizerBinding) return the same new token type "KeyboardInputModeBinding" whose #remove method can be used to remove the binding again.
    • There is also a single new method #removeCommand on KeyboardInputMode which removes all currently existing binding known for a given ICommand.

GraphML

The XML namespaces and GraphML naming conventions have been updated. The mapping from yfiles classes to the corresponding XML namespaces has been changed, as well as some of the naming conventions:

  • All platform independent model classes are now mapped to "http://www.yworks.com/xml/yfiles-common/3.0". This includes the following types
    • all graph item types
    • all default label models
    • all port location models
    • all "void" styles
    • serialization for geometric primitives
  • All platform independent graphml support classes are now mapped to "http://www.yworks.com/xml/yfiles-common/markup/3.0".
  • All platform independent framework classes are now mapped to "http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0". This includes the following types
    • primitive types (Number, Boolean, String)
  • All types and members in these namespaces use the XAML/C# naming convention in GraphML files:
    • UpperCamelCase for properties, fields, constants and enum members
  • All platform dependent library classes are now mapped to "http://www.yworks.com/xml/yfiles-for-html/2.0/xaml". These are mainly the types in namespace
    • yfiles.styles
  • All types and members in this namespace use the Javascript typical native naming convention in GraphML files:
    • actual type and property names (if applicable)
    • UPPERCASE_UNDERSCORE for fields, constants and enum members
  • The performance of parsing GraphML files has been improved. The speed-up is especially notable for large graphs with several thousands of nodes.
  • The following events have been added to signal the end of the write or parse process, respectively: GraphMLIOHandler#Parsed, GraphMLParser#Parsed, GraphMLIOHandler#Written, GraphMLWriter#Written, together with the corresponding event raiser methods.
  • SerializationProperties:
    • The new serialization property #PARSE_LABEL_SIZE optionally disables parsing of the preferred size of a label.
    • #WRITE_GRAPH_SETTINGS and #DISABLE_GRAPH_SETTINGS have been merged to a single #DISABLE_GRAPH_SETTINGS property which is interpreted according to the context where it is set.
    • #INDENT_OUTPUT has been added that allows to define whether the XML output should be properly indented.
  • A few abstract base classes have been merged:
    • AbstractXmlWriter and DirectXmlWriter have been merged into XmlWriter
    • AbstractMapperInputHandler and ComplexMapperInputHandler have been merged into MapperInputHandler
    • AbstractMapperOutputHandler and ComplexMapperOutputHandler have been merged into MapperOutputHandler
  • TypeConverter and all subclasses have been removed and were replaced either by ValueSerializers or by implementations of the new interface IMarkupExtensionConverter
  • The legacy interface IDeserializer was removed. For custom deserialization an event handler for GraphMLIOHandler#HandleDeserialization can be used.
  • Removed: ArrayValueSerializer, NullXmlWriter
  • IXamlNameMapper has been refactored to and #addXamlNamespaceMapping has been added to GraphMLIOHandler
  • QueryOutputHandlersEventArgs: The overload of #addOutputHandler taking an object id has been removed
  • XmlWriter: a property indent has been added that allow to define whether the XML output should be properly indented.
  • XmlWriter: the constructor overload taking an InternalXmlWriter as well as the corresponding property #DelegateWriter have been removed.

Collections and Utility Types

Replaced and removed a lot of the utility types.

  • Removed the yfiles.objectcollections namespace. It contained only obsolete interfaces.
  • Dissolved the yfiles.model namespace and moved its types to better matching namespaces like yfiles.collections and yfiles.view.
  • Dissolved the yfiles.system and yfiles.support namespaces and removed a lot of their types since they were not really needed. The remain types have been moved to more meaningful namespaces, mainly yfiles.view.
  • Removed EmptyCollection<T>, EmptyList<T>, CompositeEnumerable, CompositeEnumerator, CompositeListEnumerable, CompositeCollectionModel, SingleListEnumerable, SingletonCollection, SingletonList, DoubleCollection, and CollectionChangedEventArgs
  • Removed CompositeHandle<T> and CompositePositionHandler
  • Removed method IMapper#removeValue. It depends on the specific implementation of the mapper whether a mapping can be removed. If an implementation provides a way to remove a mapping, that should be preferred over setting a null value.
  • Replaced IMapperDelegate by plain functions.
  • Removed ILookupCallback and ContextLookups. Use IContextLookup instead.
  • Removed GenericYList, GenericListCell, and HashSet
  • Removed ResourceKey and ComponentResourceKey in favour of string properties.
  • Removed DefaultNodeLookup, DefaultEdgeLookup, DefaultPortLookup, DefaultLabelLookup, DefaultBendLookup and DefaultItemLookup. Instead the properties #DefaultNodeLookup, #DefaultEdgeLookup, #DefaultPortLookup, #DefaultLabelLookup and #DefaultBendLookup have been added to DefaultGraph.
  • Removed ItemDecorator<TModelItem>. Its members have been pushed down to its former sub-classes NodeDecorator, EdgeDecorator, LabelDecorator, PortDecorator, and BendDecorator.
  • The events #ItemSelected and #ItemDeselected on ISelectionModel have been merged into the #ItemSelectionChanged event.
  • EventHandler are now typed to the specific EventArgs that are used by the handler
  • Moved method GeomSupport#createSmoothedPath to GeneralPath
  • GeneralPath: Removed the #FillMode parameter from methods #createPath and #updatePath.

Layout

Layout Execution

  • LayoutExecutor:
    • The method #stop() now stops a running layout calculation as soon as possible and then immediately shows the result so far, skipping any animation. In addition, the new method #cancel() immediately cancels a running calculation and doesn’t change the GraphComponents’s #Graph unless the animation was already running.
    • The property #abortHandler has been made read-only. There is a protected factory method #createAbortHandler which can be overridden to create a custom AbortHandler implementation.
    • Labels are now taken into account for the final content rectangle and viewport animation
    • The #finishedHandler property has been removed and the API now uses Promises instead for methods #start() and #stop() to signal failures or successful completion of the operation.
    • The new property #considerViewportLimiter can be enabled to let the target viewport after a layout respect the ViewportLimiter of the GraphComponent. The ViewportAnimation has a new property #considerViewportLimiter for the same purpose.
    • Classes LayoutExecutor and LayoutGraphAdapter now have a property #automaticEdgeGrouping that automatically configures edge groups for ports with multiple incoming or outgoing edges. This feature is enabled by default.
    • Classes LayoutExecutor and LayoutGraphAdapter now have a property #fixPorts that automatically configures strong source and target port constraints for all edges in the graph. This feature is disabled by default.
  • LayoutGraphAdapter now adds data providers that map each node, edge, and label of a LayoutGraph to their corresponding IModelItem in the original IGraph. Especially, these data providers are available if a layout is run with a LayoutExecutor or the convenience methods #morphLayout or #applyLayout.

Layout API

  • The legacy hierarchic layout yfiles.hierarchic.HierarchicLayouter, yfiles.hierarchic.HierarchicGroupLayouter, and the associated legacy interfaces ILayerer, IDrawer, IMementoSupport, ILayerSequencer, together with their implementations, have been removed. Instead, IncrementalHierarchicLayouter has been renamed to HierarchicLayout and is now the only implementation of the hierarchic layout style. All associated interfaces and implementations from the namespace yfiles.hierarchic.incremental have been moved up to yfiles.hierarchic.
  • Legacy classes OrthogonalGroupLayouter and DirectedOrthogonalLayouter have been removed and their features have been incorporated in OrthogonalLayout.
  • Legacy class OrthogonalEdgeRouter and all associated classes have been removed.
  • Class HVTreeLayouter has been removed and its features have been incorporated into TreeLayout.
  • Class DefaultGraphLayout has been removed.
  • Class ParentEdgeAugmentationStage has been removed.
  • Method Graph#moveSubgraph has been removed.
  • CopiedLayoutIGraph was removed. An instance of the super type CopiedLayoutGraph with the same functionality can be obtained from factory method #createCopiedLayoutGraph in LayoutGraphAdapter.
  • The method canLayout has been removed from all layout algorithms. Previously it pretty much always returned true.
  • Introduced a new way to configure yFiles automatic layout algorithms. Class LayoutData and subclasses can be used to pass data to a layouter by setting properties instead of registering DataProvider on the graph which have to be filled with this data. This reduces the code needed to configure a layouter and is more flexible as well as reusable. As most subclasses of LayoutData are specialized for one layout algorithm, their properties provide a good overview which data can be passed to the algorithm.
  • LayoutGraphAdapter: IMappers which use ILabels as key now are correctly translated into data providers for layout algorithms.

Renamed Types

Renamed layout classes
yFiles for HTML 1.x yFiles for HTML 2.x
Main Interface
ILayouterILayoutAlgorithm
ILayouter.doLayoutILayoutAlgorithm.applyLayout
ILayouter.canLayoutremoved
Major Layout Algorithms
HierarchicLayouterremoved
HierarchicGroupLayouterremoved
IncrementalHierarchicLayouterHierarchicLayout
DirectedOrthogonalLayouterremoved, functionality incorporated in OrthogonalLayout
OrthogonalGroupLayouterremoved, functionality incorporated in OrthogonalLayout
OrthogonalLayouterOrthogonalLayout
OrthogonalEdgeRouterremoved, functionality incorporated in EdgeRouter
OrganicLayouterClassicOrganicLayout
SmartOrganicLayouterOrganicLayout
TreeLayouterClassicTreeLayout
GenericTreeLayouterTreeLayout
HVTreeLayouterremoved, functionality incorporated in TreeLayout
SALabelingGenericLabeling
GreedyMISLabelingremoved, functionality incorporated in GenericLabeling
MultiPageLayouterMultiPageLayout
MultiPageLayoutMultiPageLayoutResult
Changes in alphabetical order
AbstractLabelingAlgorithmAbstractLabeling
AbstractLayoutStageLayoutStageBase
ARTreeLayouterAspectRatioTreeLayout
BalloonLayouterBalloonLayout
BufferedLayouterBufferedLayout
CanonicMultiStageLayouterMultiStageLayout
CanonicMultiStageLayouter.LabelLayouterMultiStageLayout.Labeling
CanonicMultiStageLayouter.LabelLayouterEnabledMultiStageLayout.LabelingEnabled
CircularLayouterCircularLayout
CompactOrthogonalLayouterCompactOrthogonalLayout
ComponentLayouterComponentLayout
FamilyTreeLayouterFamilyTreeLayout
GenericTreeLayouterTreeLayout
GroupedShuffleLayouterRecursiveShuffleLayout
GroupNodeHiderHideGroupsStage
IncrementalHierarchicLayouterHierarchicLayout
com.yworks.yfiles.layout.hierarchic.incremental.HierarchicLayoutercom.yworks.yfiles.layout.hierarchic.HierarchicLayoutCore
IncrementalHierarchicLayouter.createHierarchicLayouterHierarchicLayout.createHierarchicLayoutCore
IncrementalHierarchicLayouter.HierarchicLayouterHierarchicLayout.HierarchicLayoutCore
InteractiveOrganicLayouter.disableStagesInteractiveOrganicLayout.disableAllStages
InteractiveOrganicLayouter.doLayout(long)InteractiveOrganicLayout.startLayout(long)
InteractiveOrganicLayouterInteractiveOrganicLayout
IsolatedGroupComponentLayouterIsolatedGroupComponentLayout
LayouterKeysLayoutKeys
LayoutToolLayoutGraphUtilities
MinNodeSizeStageMinimumNodeSizeStage
MISLabelingAlgorithmAbstractMISLabeling
NormalizingGraphElementOrderStageNormalizeGraphElementOrderStage
OrganicLayouterClassicOrganicLayout
OrientationLayouterOrientationLayout
PartialLayouterPartialLayout
PartitionLayouterPartitionLayout
RadialLayouterRadialLayout
RecursiveGroupLayouterRecursiveGroupLayout
ReducedScopeStageReduceScopeStage
RemoveOverlapsLayoutStageRemoveOverlapsStage
SALabelingGenericLabeling
SequentialLayouterSequentialLayout
SeriesParallelLayouterSeriesParallelLayout
ShuffleLayouterShuffleLayout
SingleCycleLayouterSingleCycleLayout
SmartOrganicLayouterOrganicLayout
SplitEdgeLayoutStageSplitEdgeStage
SubgraphLayouterSubgraphLayout
TreeComponentLayouterTreeComponentLayout
TreeLayouterClassicTreeLayout