documentationfor yFiles for HTML 3.0.0.1

Customizing Table Layout

The section Tables and Swimlanes introduces tabular and swimlane layout, lists the layout styles that support this layout, and explains common usage. You only need to read the following section if your use case is not covered by the automatic layout adapter mechanism.

The model of the LayoutGraph does not contain a specific node type for tables, swimlanes, or similar tabular groups. Instead, the services of the class LayoutGrid can be used to:

  • Define a grid-like partition consisting of rows and columns.
  • Create descriptors (LayoutGridCellDescriptor) for the cells of a grid that result from the rows and columns.
  • Assign the nodes of a diagram to these grid cells using the descriptors.

For an algorithm to respect a specific LayoutGrid, there must be nodes that are mapped to LayoutGridCellDescriptor instances that belong to that grid instance. A descriptor for a grid is created via factory methods like createCellDescriptor. Then, the descriptor can be assigned to nodes via a mapper registered with the data key LAYOUT_GRID_CELL_DESCRIPTOR_DATA_KEY.

Layout result with LayoutGrid
partition grid example smaller

The example Configuration of a hierarchical layout with LayoutGrid shows the basic setup of the layout grid seen in the above figure. Observe how the layout algorithm respects the specified organization of the nodes within the grid cells.

Configuration of a hierarchical layout with LayoutGrid
const graph = getMyGraph()
// Nodes 'n1' and 'n2' to 'n6' (not shown here).
const n1 = getMyNode()

// Create the layout algorithm and the layout data
const hierarchicalLayout = new HierarchicalLayout({
  layoutOrientation: 'left-to-right'
})
const layoutData = hierarchicalLayout.createLayoutData(graph)

// Create a grid having three rows and four columns
const grid = new LayoutGrid(3, 4)

// Query the mapper that associates nodes with grid cells from the layout data
const cellMapper = layoutData.layoutGridData.layoutGridCellDescriptors.mapper

// Assign the nodes to the cells like this:
//     +----+----+----+-------+
//     |    | n2 |    | n5 n6 |
//     +----+----+----+-------+
//     | n1 |    |    | n4    |
//     +----+----+----+-------+
//     |    |    | n3 |       |
//     +----+----+----+-------+
cellMapper.set(n1, grid.createCellDescriptor(1, 0))
cellMapper.set(n2, grid.createCellDescriptor(0, 1))
cellMapper.set(n3, grid.createCellDescriptor(2, 2))
cellMapper.set(n4, grid.createCellDescriptor(1, 3))
cellMapper.set(n5, grid.createCellDescriptor(0, 3))
cellMapper.set(n6, grid.createCellDescriptor(0, 3))

// ... and start layout calculation
graph.applyLayout(hierarchicalLayout, layoutData)

To create descriptors for the cells of a layout grid (single cells and ranges of cells), factory methods on class LayoutGrid are provided. Nodes that do not have a descriptor associated can be placed in any grid cell by a layout algorithm.

createCellDescriptor(rowIndex: number, columnIndex: number): LayoutGridCellDescriptor
Creates a descriptor for a single cell with the given row and column index.
createCellSpanDescriptor(fromRowIndex: number, fromColIndex: number, toRowIndex: number, toColIndex: number): LayoutGridCellDescriptor
Creates a descriptor that represents a two-dimensional range of cells stretching across the specified rows and columns.

In the set of all specified cells of a layout grid (single cells and ranges of cells), no two ranges of cells are allowed to overlap with each other, or overlap with a single cell. The set needs to be disjoint.