Binding Data to Graph Elements

Most notably graph algorithms expect certain information asscociated with the graph elements they process. For example, a Shortest Path algorithm from the yWorks.yFiles.Algorithms namespace needs cost data associated with the edges of a graph.

The yFiles library uses the concept of data accessors to bind this information to graph elements. The general term "data accessor" comprises both storing data and retrieving data, i.e., setter methods (write behavior) and getter methods (read behavior). The actual implementations of these two aspects are interfaces IDataProvider and IDataAcceptor. IDataProvider defines read-only behavior on the contained data, its counterpart IDataAcceptor defines write-only behavior.

The most frequently used data accessors, for example, interfaces INodeMap and IEdgeMap, have read/write behavior, i.e., they inherit from both IDataProvider and IDataAcceptor. However, there are many cases where read-only behavior is sufficient. This is especially true for situations where the supplemental data is given as a parameter to a method, for example.

In general, using data accessors presents a flexible approach, since the realization of the actual data store is not constrained to given implementations but can be extended in any imaginable way. Also, there is no restriction on the number or the implementation of each type of custom data associated with a graph element.

A Word on Subclassing Graph Elements

Normally, i.e., in popular object-oriented belief, customizing existent functionality means using inheritance. The yFiles graph implementation, however, disfavors this approach for the sake of the same technique used to provide supplemental data to graph elements. Instead of extending any of class Node or class Edge, arbitrary custom data can be bound to any instance of these classes by using data accessors.

The following topics have been discussed in this chapter:

  • The yFiles algorithms graph structure implementation basically consists of classes Graph, Node, and Edge.
  • The graph structure is directed, but also allows for undirected interpretation.
  • It knows about self-loops and parallel edges.
  • There is a clear hierarchy of responsibilities; especially, class Graph is the single authority for all structural changes.
  • To iterate over graph elements, class Graph returns enumerators. Also, there are interfaces INodeCursor and IEdgeCursor; these are typed variants of interface ICursor which defines a bidirectional cursor.
  • To store graph elements, there are classes NodeList and EdgeList; these are typed variants of class YList which defines a doubly linked list.
  • To bind arbitrary data to graph elements the yFiles library uses data accessors; data accessors can have read-only, write-only, or read/write behavior; interface IDataProvider offers read-only behavior, while interface IDataAcceptor offers write-only behavior.
  • The most frequently used data accessors are interfaces INodeMap and IEdgeMap; both have read/write behavior.
  • Instead of extending graph element classes to get customized functionality, yFiles favors the use of data accessors to bind arbitrary data to the instances of graph elements.