C

LayoutGridData<TNode, TEdge, TNodeLabel, TEdgeLabel>

Specifies one or multiple LayoutGrids for a layout.
Inheritance Hierarchy

Remarks

There are different ways to define the layout grid(s):

The simpler one is to define rowIndices and/or columnIndices for the nodes. This creates a basic LayoutGrid according to these indices. To further customize the layout grid it is possible to specify one using property grid. This enables to specify e.g. minimumWidths for columns. The layout grid may be expanded according to the indices. Specifying a layout grid using property grid but assigning no indices to nodes has no effect. If property layoutGridCellDescriptors is set, these three properties are being ignored.

The second way is to define the mapping layoutGridCellDescriptors which maps nodes to a LayoutGridCellDescriptor. If you want to work with multiple grids, this way must be chosen. Note that not all layout algorithms support multiple layout grids.

A third way is to use a LayoutExecutor with automatic table configuration.

Note that cell spanning is only supported using the layoutGridCellDescriptors.

Type Parameters

TNode

TEdge

TNodeLabel

TEdgeLabel

Examples

The following sample shows how to assign nodes to layout grid cells simply via cell indices:

Assigning nodes to layout grid cells via indices
// Create four nodes and place them in grid cells in the following way
// +---+---+---+
// | 1 | 2 | 3 |
// +---+---+---+
//     | 4 |
//     +---+

const gridData = new LayoutGridData<INode, IEdge, ILabel, ILabel>()

const node1 = graph.createNode()
const node2 = graph.createNode()
const node3 = graph.createNode()
const node4 = graph.createNode()

// Assign the nodes to their rows and columns.
// Note that you don't have to create or use LayoutGrid directly in this case.
// Setting the indices is enough.
gridData.rowIndices.mapper.set(node1, 0)
gridData.rowIndices.mapper.set(node2, 0)
gridData.rowIndices.mapper.set(node3, 0)
gridData.rowIndices.mapper.set(node4, 1)
gridData.columnIndices.mapper.set(node1, 0)
gridData.columnIndices.mapper.set(node2, 1)
gridData.columnIndices.mapper.set(node3, 2)
gridData.columnIndices.mapper.set(node4, 1)

// Run a layout with the LayoutGridData. Note that the layout-specific
// LayoutData classes that support layout grids (e.g. HierarchicalLayoutData)
// also contain a LayoutGridData that can be used directly.
graph.applyLayout(new HierarchicalLayout(), gridData)

If used this way there is no need to create a LayoutGrid instance or work with it directly. For more flexibility, e.g. to use cells that span multiple columns or rows, the LayoutGrid can be used as well:

Assigning nodes to layout grid cells via factory methods on the grid
// Create three nodes and place them in grid cells in the following way
// +---+---+
// | 1 | 2 |
// +---+---+
// |   3   |
// +-------+

const gridData = new LayoutGridData<INode, IEdge, ILabel, ILabel>()

const node1 = graph.createNode(new Rect(0, 0, 50, 50))
const node2 = graph.createNode(new Rect(0, 0, 50, 50))
const node3 = graph.createNode(new Rect(0, 0, 125, 50))
// Create a new LayoutGrid with two rows and two columns
const grid = new LayoutGrid(2, 2)
// Assign the nodes to their cells
gridData.layoutGridCellDescriptors.mapper.set(
  node1,
  grid.createCellDescriptor(0, 0),
)
gridData.layoutGridCellDescriptors.mapper.set(
  node2,
  grid.createCellDescriptor(0, 1),
)
gridData.layoutGridCellDescriptors.mapper.set(
  node3,
  grid.createRowSpanDescriptor(1),
)

// Run a layout with the LayoutGridData. Note that the layout-specific
// LayoutData classes that support layout grids (e.g. HierarchicalLayoutData)
// also contain a LayoutGridData that can be used directly.
graph.applyLayout(new HierarchicalLayout(), gridData)

Members

Show:

Constructors

Parameters

Properties

Gets or sets the mapping from a node to its column index.

When using rowIndices or columnIndices, the layout grid is configured automatically with the required number of rows and columns. Alternatively a custom one can be specified using property grid.

If nodes must be placed so that they span multiple cells in the layout grid, then layoutGridCellDescriptors must be used and the layout grid prepared accordingly.

If layoutGridCellDescriptors is set this property is being ignored.

conversionfinal

Examples

If the row and column indices can be readily inferred from the nodes, then the easiest option is usually to use the mapperFunction:

gridData.rowIndices = (node) => node.tag.row
gridData.columnIndices = (node) => node.tag.column

In case only some nodes need to be mapped to their respective row/column indices, it's sometimes easier to use the mapper:

gridData.rowIndices.mapper.set(node1, 0)
gridData.columnIndices.mapper.set(node1, 1)
gridData.rowIndices.mapper.set(node2, 1)
gridData.columnIndices.mapper.set(node2, 1)

See Also

Developer's Guide
API
rowIndices, grid, layoutGridCellDescriptors
Gets or sets the LayoutGrid.
Setting a layout grid makes sense only if rowIndices and/or columnIndices are set. If layoutGridCellDescriptors is set, this property is being ignored as LayoutGridCellDescriptors already have a link to their layout grid. If the TableLayoutConfigurator is used, this property should be ignored as it overrides the configurator's own grid, which makes the LayoutGridCellDescriptor created by the configurator invalid.
final

Examples

The LayoutGrid from this property can also be modified and subsequently used. It will be created on the first access to the property:
const row1 = gridData.grid.addRow()
const row2 = gridData.grid.addRow()
const column1 = gridData.grid.addColumn()
const column2 = gridData.grid.addColumn()

See Also

Developer's Guide
API
rowIndices, columnIndices, layoutGridCellDescriptors
Gets or sets the mapping from nodes to LayoutGridCellDescriptors.

A node is placed inside the columns/rows defined by the corresponding LayoutGridCellDescriptor. Instances can be shared among multiple nodes, but don't have to be shared. Multi-cell descriptors (i.e., descriptors that represent multiple columns/rows) are not allowed to overlap each other.

In case every node has a specific single cell, there's also the possibility to set rowIndices and columnIndices which will configure the layout grid based on the observed indices. This may be easier in some cases.

If this property is set, properties rowIndices, columnIndices and grid are not considered.

conversionfinal

Examples

There are different ways of defining the LayoutGridCellDescriptors via this property, depending on which option is the most convenient to work with. If the desired LayoutGridCellDescriptors can readily be inferred from the nodes themselves, then the most convenient option would be the mapperFunction property:

const layoutData = new GenericLayoutGridStageData()

// Define layout grid from custom data
layoutData.layoutGridData.rowIndices = (node) => node.tag.rowIndex
layoutData.layoutGridData.columnIndices = (node) => node.tag.columnIndex

// Define split edges from custom data
layoutData.splitEdges = (edge) => edge.tag.isSplitEdge

// Combine the layout data of the stage and the core layout
const compositeLayoutData = coreLayoutData.combineWith(layoutData)

graph.applyLayout(
  new GenericLayoutGridStage(coreLayout),
  compositeLayoutData,
)

When setting LayoutGridCellDescriptors for only some nodes manually it is often easier to use the mapper property:

// Create four nodes and place them in grid cells in the following way
// +---+---+---+
// | 1 | 2 | 3 |
// +---+---+---+
//     | 4 |
//     +---+

const gridData = layoutData.layoutGridData

const node1 = graph.createNode()
const node2 = graph.createNode()
const node3 = graph.createNode()
const node4 = graph.createNode()

// Assign the nodes to their rows and columns.
// Note that you don't have to create or use LayoutGrid directly in this case.
// Setting the indices is enough.
gridData.rowIndices.mapper.set(node1, 0)
gridData.rowIndices.mapper.set(node2, 0)
gridData.rowIndices.mapper.set(node3, 0)
gridData.rowIndices.mapper.set(node4, 1)
gridData.columnIndices.mapper.set(node1, 0)
gridData.columnIndices.mapper.set(node2, 1)
gridData.columnIndices.mapper.set(node3, 2)
gridData.columnIndices.mapper.set(node4, 1)

graph.applyLayout(new HierarchicalLayout(), layoutData)

See Also

Developer's Guide
API
rowIndices, columnIndices, grid, LAYOUT_GRID_CELL_DESCRIPTOR_DATA_KEY
Gets or sets the mapping from a node to its row index.

When using rowIndices or columnIndices, the layout grid is configured automatically with the required number of rows and columns. Alternatively a custom one can be specified using property grid.

If nodes must be placed so that they span multiple cells in the layout grid, then layoutGridCellDescriptors must be used and the layout grid prepared accordingly.

If layoutGridCellDescriptors is set this property is being ignored.

conversionfinal

Examples

If the row and column indices can be readily inferred from the nodes, then the easiest option is usually to use the mapperFunction:

gridData.rowIndices = (node) => node.tag.row
gridData.columnIndices = (node) => node.tag.column

In case only some nodes need to be mapped to their respective row/column indices, it's sometimes easier to use the mapper:

gridData.rowIndices.mapper.set(node1, 0)
gridData.columnIndices.mapper.set(node1, 1)
gridData.rowIndices.mapper.set(node2, 1)
gridData.columnIndices.mapper.set(node2, 1)

See Also

Developer's Guide
API
columnIndices, grid, layoutGridCellDescriptors

Methods

Combines this instance with the given layout data.
This keeps the current instance unmodified and instead returns a new instance that dynamically combines the contents of all involved instances.
final

Parameters

data: LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel>
The LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel> to combine this instance with.

Return Value

LayoutData<TNode, TEdge, TNodeLabel, TEdgeLabel>
The combined layout data.

See Also

Developer's Guide
API
CompositeLayoutData, GenericLayoutData