yFiles for HTML Release Notes

The newest major release of yFiles for HTML is version 2.3. Read the blog post Version 2.3 of yFiles for HTML to learn more about the new features, and find the list of all changes below.
The latest release is version 2.3.0.3.

See the complete changelog for the new features and changes of all versions.

Technical Requirements

  • For development, we strongly recommend an IDE with dedicated support for JavaScript, for example WebStorm and IDEA Ultimate from JetBrains, or Visual Studio Code.
  • yFiles for HTML-based web applications require an HTML5-capable browser with adequate SVG support. See the browser compatibility list for more details.

yFiles for HTML 2.3 - Changes Since 2.2.0.3

Hide Description
Open in yEd LiveDownload
yFiles for HTML 2.3 Release Notes
New isometric graph editing support
yFiles for HTML 2.3 Release Notes
New smart node aggregation algorithm
yFiles for HTML 2.3 Release Notes
New support for rich text labels

Major New Features

Isometric Drawing and Other Projections

CanvasComponent and thus GraphComponent now have an additional projection property that can be used to transform the viewport into a different parallel projection, e.g. isometric or cabinet projection. Predefined useful projections are provided as constants on the Matrix class. Interaction, including graph editing, snapping, orthogonal edge editing, etc. still work as expected, just within the new projection. That is, orthogonal edge editing becomes isometric edge editing with an isometric projection. The corresponding chapter in the Developer's Guide has all details about the customization options and the changes related to these features.

Projections are supported by all three rendering modes SVG, HTML Canvas, and WebGL.

The new Isometric WebGL Drawing Demo displays graphs isometrically and allows for adjusting the projection to rotate the graph in 3D.

Fill Area Layout and Clear Area Layout

The new ClearAreaLayout algorithm clears a user-specified area in an existing layout by moving elements. It is suitable if the rest of the layout should not change much but some free space is required, e.g., because new elements need to be inserted into the drawing or have been resized.

The new FillAreaLayout algorithm fills a user-specified area in an existing layout by moving elements into or towards it. It can make layouts around the specified area more compact and is suitable if, e.g., elements were removed from the graph or their size has changed substantially.

These new layout algorithms are part of the new layout-area module.

The Component Drag and Drop Demo uses the ClearAreaLayout algorithm to create space in the graph for newly inserted components. In the Fill Area Layout Demo, the FillAreaLayout algorithm closes gaps in the graph layout after graph elements were deleted. Finally, the Interactive Graph Restructuring Demo combines both algorithms to adjust the graph layout while sub-graphs are moved and reconnected within the graph.

Aggregation and Analysis of (Large) Graphs

Many new algorithms for analyzing graphs are now included, for example to detect components and clusters, to aggregate sub-graphs, and to calculate centrality values. In addition, the analysis algorithms now have the option to define a subset of the graph to work on. In detail, the new classes are:

  • The new NodeAggregation class provides an algorithm that intelligently aggregates nodes of (large) input graphs. It does not require complex configuration and can be used without knowledge of specific clustering or aggregation techniques.
  • The KCoreComponents class provides a component detection algorithm that finds k-cores.
  • The classes LouvainModularityClustering and LabelPropagationClustering provide two new algorithms for cluster detection.
  • The EigenvectorCentrality class offers a centrality algorithm that measures the influence of a node in a network based on the Eigenvector score.
  • The PageRank class provides a centrality algorithm that calculates the so-called page rank for the nodes.
  • The classes ChainSubstructures, CliqueSubstructures, CycleSubstructures, StarSubstructures, and SubtreeSubstructures provide new algorithms that detect isolated substructures like chains, cliques, cycles, stars, or subtrees. This can be used as an input to other (layout) algorithms.
  • The class GraphStructureAnalyzer now offers additional methods to calculate the average degree, the average weighted degree, the diameter, and the density of a given graph.

The Large Graph Aggregation Demo shows how to use the NodeAggregation algorithm to automatically analyze and explore a large graph. Developers don't need to learn the academic details of the available clustering and centrality algorithms, but can simply configure their preferred aggregation sizes to automatically create perfect user-experiences in drill-down scenarios.

The other new graph analysis algorithms are shown in either the Graph Analysis Demo or the Clustering Algorithms Demo.

Markup Label Style

The new MarkupLabelStyle interprets the label's text as markup and renders the label accordingly, for example with bold or italic parts, different colors, and different sizes. With this style, many typical text styling requirements can be realized without implementing a custom label style.

The new Markup Labels Demo shows the markup that is supported by this style. The new Markdown Label Demo realizes basic markdown rendering based on this style and the new Rich Text Label Demo shows how to implement interactive rich text editing for this style.

Bezier Edge Style

The new BezierEdgeStyle renders edges with smooth Bezier-curve paths. For intuitive interactive editing, the style comes with the same control points -or handles- that are known from other vector graphic drawing applications.

In addition, the new edge label models BezierEdgePathLabelModel and BezierEdgeSegmentLabelModel place labels optimally on curved edges rendered with this style.

The new Bezier Edge Style Demo presents this edge style and its label models. In addition, several of the existing demos with curved edges now use the new style.

Interactive Node Resizing
Resizing nodes using their handles now supports two new behaviors:
  • Center resizing keeps the center fixed and scales the node in all directions. It is active when the NodeReshapeHandleProvider.centerReshapeRecognizer is triggered which defaults to KeyEventRecognizers.ALT_PRESSED.
  • Aspect ratio resizing maintains the aspect ratio of a node. It is active when the NodeReshapeHandleProvider.ratioReshapeRecognizer is triggered which defaults to KeyEventRecognizers.SHIFT_PRESSED.
  • The NodeReshapeHandleProvider.reshapePolicy property determines how the mouse location is interpreted when aspect ratio resizing is active.

The Reshape Handle Configuration Demo showcases these different resizing behaviors.

Related to this, the new Node Selection Resizing Demo shows how to resize a selection of nodes en bloc. In contrast to the default behavior, this changes both the sizes and the locations of the nodes and not just the sizes.

Graph Builder

The old GraphBuilder, TreeBuilder, and AdjacentNodesGraphBuilder classes have been replaced in the library with more powerful but incompatible builder classes. Loading graphs from external data sources has become even easier with the new graph builder implementations. This release contains completely rewritten utility classes that can help with the creation of diagrams from one or more data sources.

With perfect TypeScript-based code completion, the new classes can load nodes, edges, labels, and their properties from one or many different sources dynamically using a declarative-like approach. Binding expressions can be used for setting the visual properties of the graph entities depending on the values in the source data.

For backward compatibility, the old GraphBuilder, TreeBuilder, and AdjacentNodesGraphBuilder classes are available as demo code in the demos-js/utils directory.

The Graph Builder Demo, the Tree Builder Demo, the Adjacency Graph Builder Demo, and the Simple Graph Builder Demo show how to load graph data from JSON using the new graph builder classes.

Improvements for Developers
  • The new development mode variant of the library includes the powerful yFiles runtime type checking. It's no longer needed to include it separately and deployment tools like webpack can strip it from "production" builds.
  • Custom object formatters for the developer tools in Google Chrome and other Chromium browsers.
  • The UMD variant of the library now also provides namespace-less names, so the modern "flat" API can easily be used with Node.JS, web workers, or RequireJS.
  • Various improvements for the optimizer.
  • The semi-automatic migration tool was rewritten to make the migration process for returning users easier. It now offers built-in TS support, an incremental mode, and clear output with source code references recognized by major IDEs.
  • Removed the create-node-library tool, as the UMD library now already includes top-level exports of all types.
  • Two new demos show how to lazily load yFiles modules with dynamic imports, namely the Webpack Lazy Load yFiles Demo and the Webpack Lazy Load Layout Modules Demo.
TypeScript Demos
A large number of demos is now available in a TypeScript version in addition to the JavaScript version. In this release, these demos include all tutorials of the Getting Started, Custom Styles, and Application Features tutorials, as well as all the new demos. More demos in TypeScript will be added in future minor and major releases, but all demos will always be available in JavaScript, too, and both versions will be identical except for language differences.

New Features

General

  • yFiles interfaces now provide a static create method that creates a new instance of the interface. The signature of this method follows the same rules as the quick interface implementation of the interface. This is especially useful in TypeScript projects since the previous JavaScript-style quick interface implementation syntax cannot be expressed with TypeScript definition files.
  • Types that support type conversion now have a static from method to explicitly invoke the conversion. This is especially useful in TypeScript projects and custom code to set properties in this way.
  • GraphML I/O now supports a static $meta attribute to annotate properties of classes with GraphMLAttributes. This alleviates the need to revert to the yFiles class framework for classes that should be serialized through GraphML.

Graph Component and Interaction

  • To improve accessibility, the new GraphComponent.ariaLiveRegion property provides an aria-live region that can be used to update screen readers. The new Accessibility Demo shows how to make use of this property.
  • The default label style now supports right-to-left text direction. Label text is properly placed and wrapped when the CSS direction of the GraphComponent's <div> element is set to rtl. The Label Text Wrapping Demo has a new graph sample with right-to-left text.
  • The GraphComponent is now prepared to provide complete control of the z-order of elements in all cases. The new Z-order Demo shows how to use this to maintain the z-order during operations there the library does not maintain this order by default, e.g. for undo and redo, expanding and collapsing groups, and clipboard commands.
  • Added support for two-finger drag and pinch touchpad gestures. The new MouseEventArgs.wheelDeltaX property provides the horizontal mouse wheel component.
  • The template styles now provide a makeObservable method to transform a regular data object into an observable object, allowing TemplateBindings to react to changes of these objects automatically.

    In addition, bindings in template styles now support "duck typing". In other words, if the bound object fires the appropriate events, the binding is updated automatically.

  • All string template styles now strip executable code from the templates to prevent attacks via GraphML. To re-enable code injection set the new static property trusted on any of these classes to true.
  • The new NodeLabelModelStripeLabelModelAdapter class allows using node label model parameters for the positioning of the row and column labels of a table.
  • A new policy has been added to the ViewportLimiter class which allows for zooming and panning towards the limits but not away from them. This prevents the viewport from "jumping" from out-of-limit coordinates into the limited bounds.
  • An Animation can now be paused and unpaused by setting the new Animator.paused property after the animation has started. This feature is used in the Network Monitoring Demo to pause the animation of the network traffic.
  • The GridVisualCreator class can now also draw only horizontal lines or only vertical lines when its gridStyle property is set to one of the new enum values GridStyle.HORIZONTAL_LINES or GridStyle.VERTICAL_LINES.

Layout

  • The EdgeRouter class and the HierarchicLayout class now support a new routing style that generates curved edge paths. This style can be specified for each edge individually using the EdgeRouterEdgeRoutingStyle.CURVED enum value and the HierarchicLayoutEdgeRoutingStyle.CURVED enum value, respectively.
  • The new layout stage CurveRoutingStage replaces polyline edge paths with curved segments using cubic bezier splines and provides a generic way to produce layouts with curved edges.
  • The new property EdgeRouterEdgeLayoutDescriptor.routingStyle allows specifying the routing style individually for each edge routed by the EdgeRouter class. Furthermore, the new properties maximumOctilinearSegmentRatio and preferredOctilinearSegmentLength on the descriptor provide means to configure the octilinear routing style.
  • The CircularLayout class now supports exterior edges that are routed around the exterior of the circle as smooth arcs. This can be specified with the new CircularLayout.edgeRoutingPolicy property.
  • The new EdgeBundlingStage class offers edge bundling for general undirected graphs. Bundling together multiple edges means that their common parts are to some degree merged into a bundled part. Edge bundling is useful to increase the readability of graph drawings with a high number of edges that connect a comparably small number of nodes.
  • The RadialLayout class now supports a user-defined layer/circle assignment strategy. This can be specified with the RadialLayoutLayeringStrategy.USER_DEFINED enum value and the layout data property RadialLayoutData.layerIds.
  • The Layout Styles Demo has been enhanced to include the following layout features and improvements:
    • Exterior edge routing for the circular layout
    • Curved edge routing and bus routing for the hierarchic layout and the edge router.
    • Integrated edge labeling for the edge router.

Algorithms

The "algorithms" part of the library provides the actual implementation of the new aggregation and analysis algorithms. Since this part uses the Graph API instead of the common IGraph API, using these implementations directly is rarely needed.

  • New methods of the GraphStructureAnalyzer and GroupAlgorithm classes compute several additional network statistics, namely GraphStructureAnalyzer.getAverageDegree, GraphStructureAnalyzer.getAverageWeightedDegree, GraphStructureAnalyzer.getDiameter, GraphStructureAnalyzer.getDensity, and GroupAlgorithm.getModularity.
  • The new NodeAggregationAlgorithm class provides an algorithm that intelligently aggregates nodes of (large) input graphs.
  • The new TransitivityAlgorithm.transitiveEdges method creates the transitive edges that connect the visible nodes in an input graph.
  • The new GroupAlgorithm.getClusteringCoefficient method computes the local clustering coefficient for each node as well as the average clustering coefficient.
  • The new GraphConnectivity.kCore overloaded methods compute the so-called k-cores of an undirected input graph.
  • The new CentralityAlgorithm.eigenvectorCentrality method computes the eigenvector centrality for each node in an undirected graph.
  • The new GroupAlgorithm.labelPropagation method implements the label propagation algorithm which detects communities in the input graph.
  • The new GroupAlgorithm.louvainModularity method detects the communities of an input graph by applying the well-known Louvain method for community detection.
  • The new CentralityAlgorithm.pageRank method provides an implementation of the page rank algorithm that computes a rank for each node.
  • The new Substructures class offers methods to detect the following graph structures: Chains, Cliques, Cycles, Stars, and Trees.

Improvements

  • The new static method IEdge.getPathPoints returns an IListEnumerable that contains a snapshot of the source port location, followed by the bend locations, followed by the target port location of an edge.
  • The ITable.addLabel method no longer accepts label model parameters that do not support IStripe instances. Previously node label models could be used but did not work properly at runtime.
  • The new Fill.hasSameValue method can be used to check two fills for equality.
  • The classes DefaultFolderNodeConverter and FoldingEdgeConverterBase provide a new protected method createPreferredLabelSize to allow for overriding the default implementations.
  • The performance of GraphML serialization and deserialization was improved.
  • The parameter of all predicate functions is now annotated as not-null which makes it more comfortable to implement these functions.
  • BaseClass has now overloads with more than one type parameter, making the TypeScript syntax for implementing several interfaces less complicated.

Collections

  • The interfaces IEnumerable and IList now provide the methods indexOf and findIndex which behave similarly to the corresponding functions of JavaScript Arrays. The method IList.indexOf now has an optional parameter fromIndex.
  • The IList interface now declares the methods push, pop, shift, and unshift that work in the same way as the corresponding methods of JavaScript arrays.
  • The static methods Point.from, Size.from and Rect.from can now convert any object that provides at least properties like x, y, width, and height.
  • The new Point.interpolate method calculates the linear interpolation between two points.
  • The IMap interface now extends the IMapper interface to facilitate registering instances of maps in the MapperRegistry.
  • A native JavaScript Map can now be converted automatically to IMapper.

View

  • The DOM update performance when elements in the back of the rendering stack got removed or changed their z-Order was massively improved.
  • The GraphOverviewComponent is now rendered with HTML Canvas instead of SVG by default. This results in better performance and was always the intended behavior.
  • The performance of general text measuring for TextMeasurePolicy.SVG was improved for cases in which a lot of measurements are done in a short period of time, e.g. during bulk label creation.
  • The CanvasComponent.fitContent method now respects the limitedFitContentZoom property if a ViewportLimiter is enabled.
  • The CanvasComponent.updateContentRect method now throws an exception if an element on the canvas provided invalid bounds, e.g. one with infinite values.
  • The methods raise, lower, toFront, and toBack on class GraphModelManager are now virtual.
  • The new GraphModelManager.provideUserObjectOnMainCanvasObject property can be set so that a model is accessible as its main canvas object's user object.
  • The new SvgExport.cssStylesheet property allows for defining CSS rules that are added to the exported SVG. Additionally, setting it explicitly to null lets the SvgExport class automatically add all relevant CSS rules from available stylesheets to the exported SVG.
  • The classes NodeStyleLabelStyleAdapter, NodeStylePortStyleAdapter, and NodeStyleStripeStyleAdapter now propagate the tags of labels, ports, and stripes to the node that's rendered with the node style.
  • The rendering performance of the DefaultLabelStyle class was improved when setting a maximumSize.
  • To make overriding easier, the overloaded method IPathGeometry.getTangent that has a segment index and a ratio as parameters was renamed to getTangentForSegment. The corresponding methods of EdgeStyleBase and GeneralPath were renamed as well.
  • To make overriding easier, the overloaded methods GraphModelManager.getCanvasObjectGroup now have distinguishable names, namely getNodeCanvasObjectGroup, getEdgeCanvasObjectGroup, etc.

Graph Component's New Projection Feature

  • The CanvasComponent class has additional methods to convert between the world, the new intermediate, and the view coordinate system.
  • The MarqueeSelectionInputMode, NavigationInputMode, and HandleInputMode classes now have a property useViewCoordinates which controls whether the input mode draws its decorations and processes input in view coordinates.
  • When the MarqueeSelectionInputMode class uses view coordinates, the resulting shape of the marquee in world coordinates may not be a rectangle. Therefore, the MarqueeSelectionEventArgs class now has a path property of type GeneralPath to describe the marquee shape and a usePath property that determines whether the path property or the rectangle property shall be used.
  • The EdgeDecorationInstaller, RectangleIndicatorInstaller, PointSelectionIndicatorInstaller, and DefaultPortCandidateDescriptor classes now have a useViewCoordinates property that controls whether the decoration is rendered in view coordinates.
  • The ContextConfigurator.calculateScaleForHeight and calculateScaleForWidth methods now take an additional optional parameter with the projection to correctly calculate the scale factor when a projection is used.
  • The CreateEdgeInputMode.measureDistance method now has to return the distance in view coordinates if and only if CanvasComponent's projection is used.
  • The IRenderContext interface now has additional members that are useful with the new projections feature: projection, intermediateTransform, worldToIntermediateCoordinates, and intermediateToViewCoordinates.

Interaction

  • Zooming speed of two-finger scroll and pinching was improved for Chrome and Firefox on macOS.
  • The default position handler for edges now creates fewer additional bends when the edge is dragged while orthogonal edge editing is enabled.
  • The new factory method OrthogonalEdgeEditingContext.createOrthogonalEdgeDragHandler can be used for custom node position handler and reshape handler to keep orthogonal edges attached to a node orthogonal during the drag/reshape gesture.
  • A maximumBoundingArea can now be set on the classes ReshapeHandleProviderBase, ReshapeHandlerHandle, RectangleHandle, and ReshapeRectangleContext to restrict reshaping to stay inside the given bounds.
  • The new NodeDecorator.reshapeHandlerDecorator property simplifies using custom IReshapeHandler implementations for nodes.
  • The new ReshapeRectangleContext.ratio property specifies the width/height ratio that is kept for aspect ratio resizing.
  • The new classes NodeReshapeHandleProvider and NodeReshapeHandlerHandle are used as the default implementation for node resize handles.
  • With the new ReshapeRectangleContext.reshapePolicy property, INodeReshapeSnapResultProvider implementations can respect the node aspect ratio for according resize gestures.
  • The ReshapeHandlerHandle class has new getters for the IReshapeHandler and the HandlePositions.
  • The new NavigationInputMode.fitContent method is called after collapse, expand, enter, and exit operations if the fitContentAfterGroupActions property is enabled.
  • The NavigationInputMode class doesn't fit the content anymore after expand and collapse operations if an autoGroupNodeAlignmentPolicy other then NodeAlignmentPolicy.NONE is used.
  • An optional parameter preferredSnapType has been added to the SnapLineSnapResult constructor and the SnapResults.createSnapLineSnapResult factory method.
  • The GraphClipboard and GraphEditorInputMode class now provide the new ElementsDuplicated event that occurs when a duplicate operation finished successfully.
  • The undo and redo methods of the UndoEngine class now throw an exception with the name InvalidOperationError if the current state does not allow performing undo or redo. Previously, the name was either NotSupportedError or just Error.
  • The classes ResizeStripeInputMode, DropInputMode, and HandleInputMode now have an isDragging property indicating whether a drag currently is in progress.
  • The CompositeLabelModel class now supports label snapping.
  • The SnapResults.createResizeSnapResult method now takes a Point as delta parameter instead of a number so it is possible to create resize snap results where the orientation of the mouse delta differs from the orientation of the snapped size.
  • The properties gridSnapDistance and gridSnapType of the GraphSnapContext class have been pulled up to the SnapContext class.
  • The zoom-invariant gridSnapDistance property has been added to the CollectSnapResultsEventArgs class.
  • It is now easier to customize the GroupingNodePositionHandler class. The boolean properties adjustParentNodeLayout, moveChildNodes and reparentingEnabled have been added to control whether an ancestors' node layout should be adjusted when a node is moved, to not move the contents of a group node when a group node is moved or forbid any interactive reparenting.
  • The GraphEditorInputMode.requeryHandles method has been made public and can now be used to refresh the displayed handles if IHandleProvider implementations return different handles over time.

Layout

  • Frequently used types of the layout part have now nullability annotations.
  • The LayoutExecutor class now generates more specific port constraints with the FixPorts property enabled, resulting in better edge paths.
  • The methods IGraph.applyLayout and GraphComponent.morphLayout now support the configuration of their internal LayoutExecutor instance. Hence, options like viewport animation can be adjusted without switching to the LayoutExecutor class.
  • The EdgeRouter class now provides improved support for early exits. The routing algorithm now often reacts more sensibly to the case that the specified maximumDuration is reached.
  • If the EdgeRouter algorithm runs with highly restricted maximum time or when it gets stopped by means of an AbortHandler, it now better adheres to the minimum edge-to-edge distance.
  • The new HideGroupStage.resetEdgePaths property allows specifying whether or not the stage resets the path of edges incident to group nodes.
  • The ComponentLayout class now correctly considers node and edge labels when using the packed layout styles, e.g., ComponentArrangementStyles.PACKED_RECTANGLE or ComponentArrangementStyles.PACKED_CIRCLE. Previously, labels could overlap other elements when using these component arrangement styles.
  • The new DefaultPortAllocator.considerFixedPorts property allows specifying whether edges with strong port constraints or fixed port candidates should be considered during the port assignment. Previously, such edges were ignored which could lead to intersections with the ports of the other edges. This new feature is enabled by default.
  • The PartialLayout class now produces more stable results if it is multiple times applied to the same input graph and the subgraphPlacement property is set to SubgraphPlacement.FROM_SKETCH.
  • Constructor overloads have been added to the classes SingleItem, ItemCollection, ItemMapping, and ContextItemMapping that initialize one of their properties on construction.
  • If the mapper property of HierarchicLayoutData.edgeDirectedness is directly accessed (not explicitly set) its default for unset values is 1.0 (in other words, such edges are considered to be directed).
  • If the mapper property of OrganicLayoutData.groupNodeModes is directly accessed (not explicitly set) its default for unset values is GroupNodeMode.NORMAL. This doesn't change the result of the layout.
  • For the rootPlacements, subtreeRoutingPolicies, and subtreeAspectRatio properties of the AspectRatioTreeLayoutData class, the type of the mapped values has been made nullable. For null or unset values, the settings on the AspectRatioTreeLayout will now be taken.
  • All PortCandidate.createCandidate methods now support type conversion for the port direction.

Analysis

  • The GraphCentrality and ClosenessCentrality analysis algorithms now calculate the centrality individually per component instead of returning a centrality value of 0.0 for nodes in graphs that are not connected.
  • In a single node graph, the single node's closeness centrality and graph centrality value is now 1.0. (Previously, it was infinity.) This also affects derived values such as minimum, maximum, and normalized centrality. The backing algorithms in the Centrality class are unchanged.
  • When EdgeBetweennessClustering and FeedbackEdgeSet are executed, the specified edge weights are checked and in case they are not positive or finite, an exception is thrown.
  • The GraphStructureAnalyzer class has now methods to determine whether there are multiple edges between the same pair of nodes.

Bugfixes

  • Fixed a bug in FoldingManager where a predicate change in a FilteredGraphWrapper which serves as the master graph could trigger an exception if a child of a folder node has been hidden.
  • Undo and redo of additions and removals of bends on folding edges now correctly restores the bends at the location they had at the time of removal.
  • Fixed a bug in the GraphCopier class which caused the LabelCopied event to be dispatched twice for port labels on folder nodes.
  • Using ES6 classes together with GraphMLIOHandler.addXamlNamespaceMapping(xmlNamespace, module) no longer results in an exception when writing GraphML.
  • We now make sure that types that are structural compatible for TypeScript are actually different in the TypeScript typings. Otherwise, the overload resolution provided by the typings wouldn't reflect the actual outcome. This affected especially the EdgeDpKey and NodeDpKey classes and the IMapperRegistry.createMapper methods.
  • The methods createNodeMapper and createEdgeMapper of class YGraphAdapter are no longer interchanged. Previously, the createNodeMapper method created an IMapper for keys of type IEdge and vice versa.

View

  • The methods ICanvasObject.above and below don't unnecessarily trigger IRenderContext.ChildVisual anymore.
  • Fixed a bug that sometimes callbacks registered via the IRenderContext.setDisposeCallback method have not been called when the visual was disposed.
  • Scrolling the viewport with the mouse wheel no longer scrolls in the wrong direction if the mouse wheel is set to scroll one page at a time (instead of several lines).
  • Edges between deeper nested nodes are now displayed correctly in front of a common ancestor after that ancestor has been added or removed.
  • Fixed a bug which caused the ZOOM_TO_CURRENT_ITEM command to ignore the ViewportLimiter of the corresponding CanvasComponent.
  • The CanvasComponent.zoomTo method no longer triggers two ViewportChanged events.
  • The scrollbars of a GraphComponent are no longer missing if it was lazily initialized with the policy ScrollBarVisibility.ALWAYS.
  • Setting the CanvasComponent.useGlassPane property to true now enables a glass pane as intended.
  • The CanvasComponent.SizeChanged event now also returns the correct old size if the ErrorHandling.CatchErrors property is not enabled.
  • Fixed a bug where setting the SvgExport.encodeImagesBase64 property to true together with setting the SvgExport.inlineSvgImages property to false would encode SVG images as base64 bitmap images.
  • Fixed a bug where SVG images with data URLs as source would not be inlined when the SvgExport.inlineSvgImages property was set to true.

Styles

  • The TemplateBinding.bounds property is no longer undefined.
  • Setting the fill of an Arrow of type SHORT now works also with automatic type conversion.
  • When setting a new Font whose textDecoration property had the value NONE, this TextDecoration was not applied to the SVG text element.
  • The TextRenderSupport.addText method now also applies the properties of the given font to the text element, as stated in the documentation.

Interaction

  • Pinch-zoom no longer stops periodically during the gesture.
  • Fixed a touch interaction bug in Safari that resulted in a freeze of the CanvasComponent when lifting two fingers at once.
  • Using a custom input element for editing label text now works correctly since the GraphEditorInputMode.editLabelCore method now sets the label text to the TextEditorInputMode.editorText property instead of to its own internal text input element.
  • The NavigationInputMode.fitContentAfterGroupActions property is no longer ignored when the NavigationInputMode class is used as a child input mode of the GraphEditorInputMode class.
  • The NavigationInputMode class now also updates the CanvasComponent.contentRect property when it is not used as a child input mode of the GraphEditorInputMode class.
  • The SnapContext.gridSnapDistance and SnapContext.snapDistance properties are no longer incorrectly interpreted in world coordinates when calculating snapResults.
  • Orthogonal edge editing does not add bends anymore to edges that are marked as not orthogonal.
  • The paste and duplicate operations now honor the GraphEditorInputMode.shouldSelect predicate.
  • Fixed a bug which could cause an input mode to be left in an undefined state if another input mode has been activated in an event handler of the first input mode. This usually resulted in the wrong cursor being displayed.
  • The property name reported by the UndoEngine.PropertyChanged event is now always equal to the name of the corresponding property. Previously, some of the reported names started with an uppercase letter.
  • Under rare circumstances, tooltip elements were not removed from the DOM after their leave animation ended. There is now a configurable maximum duration for such animations after which the tooltip is removed in any case. The default value is 5 seconds.

Layout

  • The HierarchicLayout class no longer throws an exception that was previously triggered in some cases with bus structures and in conjunction with layering constraints.
  • The HierarchicLayout class no longer throws an exception that was previously triggered in some cases with bus structures and in conjunction with undirected edges.
  • Fixed a bug in the HierarchicLayout class that could cause unnecessary (double) edge crossings when the algorithm was executed in incremental layout mode with edge grouping and alternative group bounds.
  • The NodePlacerBase.placeSubtree method now clears its internal caches, especially the graph cached in field NodePlacerBase.graph. Previously, holding onto a node placer instance could lead to subtle memory leaks.
  • The EdgeRouter class no longer produces unnecessary overlaps for cases where the source or target node is overlapped by (several) label elements. This generally improves the ability of the router to deal with input that contains source/target nodes that are overlapped by other elements and are required to be crossed by an edge route.
  • The EdgeRouter class now correctly observes inputs where the user specifies buses with both fixed and non-fixed edges at the same time.
  • The EdgeRouter class no longer throws an exception when points specified with the EdgeLayoutDescriptor.intermediateRoutingPoints property are too close together.
  • The EdgeRouter class no longer yields edge labels that overlap with unrelated group nodes when using the integrated label placement feature.
  • Resolved a bug in the EdgeRouter class which caused that grouped edges were sometimes actually not grouped together. This mainly appeared in conjunction with a large value of either the minimum first or last segment length.
  • The EdgeRouter class no longer produces an exception for some rare cases with fixed grouped edges and octilinear paths.
  • The OrganicLayout class no longer throws an exception when having a PartitionGrid and at the same time the scope set to SUBSET or MAINLY_SUBSET where all nodes of the graph are marked as affected (could have used scope ALL instead).
  • The EdgeRouter class now properly considers ports provided by a PortCandidateSet when the set contains multiple candidates with single capacities and where the candidates are on the same node side. Previously, it could happen that only one of several edges connecting to the node correctly considered the ports.
  • The EdgeRouter class does no longer use the same fixed PortCandidate out of a specified PortCandidateSet if another non-saturated candidate can be chosen. Thus, overlapping edge segments are avoided.
  • The OrthogonalSegmentDistributionStage no longer produces degenerated (very large or small) coordinates for edges that contain zero-length segments, that is, duplicate edge path points.
  • The ChannelEdgeRouter class no longer yields degenerated routing results (very large or small coordinates) when using the OrthogonalPatternEdgeRouter as path finder strategy and setting its minimum distance to zero. The OrthogonalPatternEdgeRouter class now avoids duplicate points when the minimumDistance property is set to zero.
  • The AspectRatioTreeLayout class no longer crashes, causing a stack overflow, when applied to a large chain graph.
  • The RecursiveGroupLayout class now correctly moves child nodes along with their group also in case the RecursiveGroupLayout.coreLayout is null. Previously, if additionally a group node had a specific layout algorithm associated with it, the content was not correctly moved along. If the core layout was not null, the issue did not occur.
  • The EdgeRouter class now considers the correct shape of non-affected, fixed edges. Previously, it sometimes incorrectly parsed their shape which could lead to undesired effects like incorrect path cost calculation of affected edges.
  • The BalloonLayout class no longer crashes due to a stack overflow for inputs containing very long chain graphs.
  • Fixed a bug in the HierarchicLayout class that in some cases caused a violation of the minimum first or last segment length. The bug was only triggered when the minimum length values were relatively large.
  • The TreeMapLayout class no longer produces results that may have infinite coordinates.

Analysis

  • The HierarchicalClustering class no longer throws an exception when applied to an empty graph.
  • The results of the Chains class are now correct for undirected cycles, too. If such cycles are not connected to other parts of the graph, the nodes collection of a resulting Path could have been in an incorrect order.
  • The ClosenessCentrality class no longer calculates NaN as results of the normalizedNodeCentrality property if the graph consists of one single node. Instead, the value of the normalizedNodeCentrality property is now positive infinity.
  • The ClosenessCentrality.run method no longer throws an exception for unconnected graphs. Instead, all values of the nodeCentrality and normalizedNodeCentrality properties will be 0.0 as the documentation states.
  • The EdgeBetweennessClustering.run method no longer throws an exception with its default setting for the maximumClusterCount property.

Incompatible Changes

See the Migration Guide for more details and advice on migrating.

Incompatible API Changes

  • The GraphBuilder, TreeBuilder, and AdjacentNodesGraphBuilder classes have been replaced in the library with more powerful but incompatible builder classes. Drop-in replacement classes that resemble the API of the previous builders, named SimpleGraphBuilder, SimpleTreeBuilder, and SimpleAdjacentNodesGraphBuilder, are available as demo code in the demos-js/utils directory. See the migration guide for details.
  • The KMeansClusteringDistanceMetric enum was removed in favor of the DistanceMetric enum with the same members.
  • The ToolTip class has now a constructor without parameters to make custom implementations easier.
  • To make overriding easier, the overloaded method IPathGeometry.getTangent that has a segment index and a ratio as parameter was renamed to getTangentForSegment. The corresponding methods of EdgeStyleBase and GeneralPath were renamed as well.
  • To make overriding easier, the overloaded methods GraphModelManager.getCanvasObjectGroup now have distinguishable names, namely getNodeCanvasObjectGroup, getEdgeCanvasObjectGroup, etc.
  • To support right-to-left text direction, a new optional rightToLeft parameter with default value false was added to the methods DefaultLabelStyleRenderer.addTextElements and TextRenderSupport.addText.
  • The DefaultLabelStyleRenderer.addTextElements method now consumes an SVGElement as first parameter. For the default left-to-right text direction, this is an SVGTextElement like before. For the newly supported right-to-left text direction, this is an SVGGElement.
  • The NodeReshapeSnapResultProvider.getSnapLines method now takes CollectSnapResultsEventArgs as additional parameter.
  • Several methods related to snapping now take a Point instead of a number as delta parameter. In detail, these are SnapResults.createResizeSnapResult, NodeReshapeSnapResultProvider.addSnaplineSnapResult, NodeReshapeSnapResultProvider.addGridLineSnapResult, and NodeReshapeSnapResultProvider.addSameSizeSnapResult.
  • The HierarchicalClusteringResult.dendrogramRoot property can now return null if the result has been obtained from an empty graph.
  • The optional IPortLocationModelParameter and IPortStyle parameters of the IGraph.addPort method can now be null.
  • The ModelManager.unInstall method has been renamed to the canonical name uninstall.
  • The singleton returned by the static DefaultEdgePathCropper.INSTANCE property has been moved to the IEdgePathCropper.INSTANCE property. This singleton doesn't implement DefaultEdgePathCropper and similar singletons are defined on their corresponding interface, too.
  • The method CanvasComponent.createInputModeContext is protected again, after having been made public accidentally previously.
  • The GraphEditorInputMode.requeryHandles method is now public.
  • The static methods createDelegate and dynamicInvoke of delegate have been removed. They were never intended to be part of the public API and didn't work as intended in all cases.
  • The methods getPreferredSize and getPreferredSizeCore of (String)TemplateNodeStyle, (String)TemplatePortStyle, and the corresponding renderer implementations have been removed since they were never used by the library and returned no meaningful value.
  • The methods createNodeMapper and createEdgeMapper of YGraphAdapter are no longer interchanged. Previously, createNodeMapper created an IMapper for keys of type IEdge and vice versa.
  • Some methods of the YList class have been replaced to be consistent with the new methods of IList and the corresponding methods of JavaScript arrays. Note that YList is a special-purpose list implementation that is typically only used when implementing a layout customization. In detail, pop has been renamed to shift, popLast has been renamed to pop, and push has been changed to be in line with IList.push: it now returns the length of the list instead of a ListCell.

Changes in Default Behavior

  • The GraphOverviewComponent is now rendered with HTML Canvas instead of SVG by default. This results in better performance and was always the intended behavior. You can switch to SVG rendering with the GraphOverviewComponent.renderMode property.
  • The NavigationInputMode.adjustContentRect method doesn't fit the graph bounds in the viewport anymore.
  • The NavigationInputMode class doesn't fit the content after expand and collapse operations anymore. This behavior can be restored by setting the autoGroupNodeAlignmentPolicy property to a value other than NONE and the fitContentAfterGroupActions property to true.
  • The NavigationInputMode.fitContentAfterGroupActions property now is false by default.
  • The ViewportLimiter no longer jumps to the limited viewports if the current viewport is outside the limited area. This behavior can be restored by setting the ViewportLimiter.limitingPolicy property to LimitingPolicy.STRICT.
  • The default value of the MoveViewportInputMode.pinchZoomThreshold property has been changed from 100 to 50 to prevent pinch gestures from stopping periodically.
  • All string template styles now strip executable code from the templates to prevent attacks via GraphML. To re-enable code injection set the new static property trusted on the classes StringTemplateNodeStyle, StringTemplateStripeStyle, StringTemplateLabelStyle, or StringTemplatePortStyle to true.
  • The GraphCentrality and ClosenessCentrality analysis algorithms now calculate the centrality individually per component instead of returning a centrality value of 0.0 for nodes in graphs that are not connected.
  • HierarchicLayoutData.edgeDirectedness property: If its mapper property is directly accessed (and not explicitly set), its default for unset values is now 1.0 instead of 0.0. This means that such edges are now treated as directed instead of undirected.
  • For the rootPlacements, subtreeRoutingPolicies, and subtreeAspectRatio properties of the AspectRatioTreeLayoutData class, the type of the mapped values has been made nullable. For null or unset values, the settings on the AspectRatioTreeLayout will now be taken. This is the documented behavior, though.
  • The value of the read-only property EdgeRouter.partition is now null after applying the routing algorithm. It is only intended to be used during the execution. Previously, it was cached, even though the documentation stated otherwise.

Changes When using a Projection

  • The view coordinate system now includes the projection. For customers who do not use a projection, nothing will change. However, when the (old) view coordinate system has been used to render parts of the visualization in a zoom-invariant manner, the equivalent now is called the intermediate coordinate system. The view coordinate system is still necessary when coordinates relative to the control are needed, e.g. for tooltips or a context menu.
  • When using the new projections feature, the CanvasComponent.contentRect property no longer has an effect on scrollbars or the GraphComponent.fitGraphBounds method.
  • SvgExport.viewWidth and SvgExport.vViewHeight are no longer used for the exported image dimensions when using a projection. If you need to know the size of the resulting image, this can be obtained from the image after export.
  • Visuals that are rendered in view coordinates relative to the viewport may appear in a different location when exporting an image.
  • CanvasComponent ignores its ViewportLimiter when projections are used.

Deprecations

  • The LabelStyleBase.createLayoutTransform method has a new overload with the render context as the first parameter to take non-identity projections of the corresponding CanvasComponent into consideration. Without this context, this method cannot respect a projection and, consequently, the overload with the previous signature is now deprecated.
  • The properties EdgeRouter.polylineRouting, EdgeRouter.preferredPolylineSegmentLength and EdgeRouter.maximumPolylineSegmentRatio are now deprecated. To enable polyline routing, specify EdgeRoutingStyle.octilinear as routing style via EdgeLayoutDescriptor.routingStyle. The other two properties are also replaced by respective properties on the EdgeLayoutDescriptor class.

Demo Changes

  • Our simple RequireJS demo implementation is no longer part of the package. The demos now use module loading instead, and we always recommended to use the official RequireJS implementation.