Containers

Classes NodeList and EdgeList, the typed descendants of class YList, are the most frequently encountered yFiles data structures to store graph elements. Figure 12.6, “yFiles graph element containers” shows their relationship.

Figure 12.6. yFiles graph element containers

The yFiles graph element containers.

Common to all lists is their support for the methods from interface ICollection via the implementation in class YList. Beyond this implementation, class YList provides advanced list access and manipulation services which strongly rely on the possibilities offered by class ListCell.

High-Level Features

In addition to the methods from interface ICollection there are several further methods offered. For instance, it is possible to add elements explicitly to the front or the back of a list. Also, removing elements from the list is possible from both the front and the back. Note that the method names for removing elements from either end of the list resemble those of abstract data type stack.

Other methods offer list sorting, reversing a list, or the splicing of two lists into one.

Example 12.9. Adding elements to and removing elements from a list

// 'list' is of type yWorks.yFiles.Algorithms.YList.

// Add new elements to either end of the list.
list.AddFirst("I am the first node!");
list.AddLast("I am the last node!");

// Remove elements from either end of the list.
list.Pop();
list.PopLast();

To iterate over the elements of the list it provides an enumerator and an ICursor (respectively INodeCursor and IEdgeCursor with classes NodeList and EdgeList). See also the discussion in the section called “Iteration Mechanisms”.

Example 12.10, “Efficiently removing elements from a list using a cursor” shows how to efficiently remove an element from a list using a cursor. The cursor directly points to the element, there is no need to search the list.

Example 12.10. Efficiently removing elements from a list using a cursor

// 'list' is of type yWorks.yFiles.Algorithms.YList.

// Remove unwanted objects from the list.
for (ICursor c = list.Cursor(); c.Ok; c.Next()) {
  if (IsUnwanted(c.Current)) {
    list.RemoveAt(c);
  }
}

Low-Level Features

Class ListCell is the building block of the doubly linked list structure. It knows both its predecessor and its successor, and provides read/write behavior for the actual data it is holding.

Example 12.11. Using class ListCell

// 'list' is of type yWorks.yFiles.Algorithms.YList.

// Get the first cell of the list.
ListCell firstCell = list.FirstCell;

// Get the actual data the cell is holding.
object obj = firstCell.Info;

// Change the actual data.
firstCell.Info = "Updated Data.";

Using an instance of type ListCell, for example, it is possible to have fast access to the preceeding, respectively succeeding cell from the containing list, or to insert new cells relatively to already contained ones. By way of the successors (predecessors) of a ListCell instance, direct iteration over the elements of a list is possible.

Example 12.12. Directly iterating over the cells of a YList

// 'list' is of type yWorks.yFiles.Algorithms.YList.

// Directly (backward) iterate over the list.
for (ListCell lc = list.LastCell; lc != null; lc = list.PredCell(lc)) {
  if (ConditionIsSatisfied(lc.Info)) {
    // Insert a new cell with given data relatively to the held reference cell.
    // The newly allocated cell will be returned.
    ListCell newCell = list.InsertBefore("Prepended Data.", lc);
  }
}