documentationfor yFiles for HTML 3.0.0.1

Binding Data to the LayoutGraph and its Items

The changes described in this chapter only affect users who work directly with the LayoutGraph API of yFiles. This is necessary only if you implement your own ILayoutAlgorithm, ILayoutStage, or another customization of the layout part. Therefore, this migration guide is not relevant for users who just apply a layout on an IGraph. To learn about how to bind custom input data in that case, please see the corresponding migration chapter.

The new class LayoutGraphContext now manages all supplementary data for the graph and its elements, which can be used by layout algorithms during computation. Therefore, it replaces methods LayoutGraph.addDataProvider and LayoutGraph.removeDataProvider of yFiles for HTML 2.6.

The interface IDataProvider has been removed. In yFiles for HTML 3.0, its replacement is the generic interface IMapper<K,V>.

Data Keys

Like before, data is stored on the graph using unique lookup key instances, typically defined by layout algorithms. Client code or LayoutData can supply additional data associated with a particular key. Layout algorithms can then retrieve this data using these keys and use it as input.

Keys are now called data keys. The base class for data keys is DataKey<TValue>. This class replaces the former DpKeyBase<TValue>. For items, like nodes and edges, there are specific keys, namely NodeDataKey<TValue> and EdgeDataKey<TValue>.

All the static keys on the layout algorithms have been renamed accordingly; for example, xyzDpKey is now xyzDataKey. The data storage and retrieval methods in the layout API are now generic and type safe.

Data for Specific Items (Nodes, Edges, Labels)

Adding and retrieving item data using an IMapper
// Create a mapper and set values for two specific edges
const edgeMapper = new Map()
edgeMapper.set(edge1, 4.5)
edgeMapper.set(edge2, 1.0)

// Register the mapper using an existing DataKey
// Note: corresponds to old code graph.addDataProvider(EdgeThicknessDataKey)
graph.context.addItemData(
  HierarchicalLayout.EDGE_THICKNESS_DATA_KEY,
  edgeMapper
)

// ... Somewhere else: get the mapper from the graph
// Note: corresponds to old code graph.getDataProvider(EdgeThicknessDataKey)
const mapper = graph.context.getItemData(
  HierarchicalLayout.EDGE_THICKNESS_DATA_KEY
)

// Create a mapper and set values for two specific edges
const edgeMapper = new Map<LayoutEdge, number>()
edgeMapper.set(edge1, 4.5)
edgeMapper.set(edge2, 1.0)

// Register the mapper using an existing DataKey
// Note: corresponds to old code graph.addDataProvider(EdgeThicknessDataKey)
graph.context.addItemData(
  HierarchicalLayout.EDGE_THICKNESS_DATA_KEY,
  edgeMapper
)

// ... Somewhere else: get the mapper from the graph
// Note: corresponds to old code graph.getDataProvider(EdgeThicknessDataKey)
const mapper = graph.context.getItemData(
  HierarchicalLayout.EDGE_THICKNESS_DATA_KEY
)

It is not required to always provide an IMapper<K,V>. Providing a getter/callback can be more convenient. This is a good replacement for code where in yFiles for HTML 2.6 a custom DataProviderBase was added.

Adding data by using a getter function
// Add item data for nodes by using a getter/callback function
graph.context.addItemData(LayoutKeys.NODE_MARGIN_DATA_KEY, (node) =>
  node.degree === 0 ? Insets.EMPTY : new Insets(10)
)

// Add item data for nodes by using a getter/callback function
graph.context.addItemData(
  LayoutKeys.NODE_MARGIN_DATA_KEY,
  (node: LayoutNode) =>
    node.degree === 0 ? Insets.EMPTY : new Insets(10)
)

Global Data for the Graph

Previously, registering a single value with the LayoutGraph required using the IDataProvider interface, which has been removed. The DataProviders.createConstantDataProvider factory method was useful in that scenario. The replacement is the addData<TValue> method.

Adding a single value to the LayoutGraph
// Add a single rectangle as data using the key provided as first argument
graph.context.addData(
  ClearAreaLayout.EXPANDED_NODE_ORIGINAL_BOUNDS_DATA_KEY,
  new Rect(0, -20, 100, 200)
)

Amending and Removing Data

In previous versions of yFiles for HTML 2.6, temporarily changing, replacing, or removing data required manually removing an IDataProvider, addding a different one, and finally, once done, re-adding the original instance. While this approach is still possible, the new LayoutGraphContext now uses layers. Layers can be pushed onto and popped from the context. Pushing a layer creates a new layer, and any item data registered with a key on this new layer makes previously registered data invisible. This approach makes temporary changes much clearer.

Using the layers of the context
// Push a new layer onto the context
graph.context.pushLayer()

// Register margins data, in this case defining a margin of 40 pixels for each node
graph.context.addItemData(
  LayoutKeys.NODE_MARGIN_DATA_KEY,
  (_) => new Insets(40)
)

// ... Do something, e.g., apply an algorithm. At this moment the 40 pixels margin is visible
new OrganicLayout().applyLayout(graph)

// Remove one context layer. This way the state will be equal to the original one. Margins are now as
// reset to whatever they were. It does not matter if margins were even registered or not.
graph.context.popLayer()