Specifies one or multiple LayoutGrids for a layout.
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.
Examples
The following sample shows how to assign nodes to layout grid cells simply via cell 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:
// 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)
Type Parameters
- TNode
- TEdge
- TNodeLabel
- TEdgeLabel
Type Details
- yFiles module
- algorithms
Constructors
Parameters
A map of options to pass to the method.
- layoutGridCellDescriptors - ItemMapping<TNode,LayoutGridCellDescriptor>
- The mapping from nodes to LayoutGridCellDescriptors. This option either sets the value directly or recursively sets properties to the instance of the layoutGridCellDescriptors property on the created object.
- grid - LayoutGrid
- The LayoutGrid. This option either sets the value directly or recursively sets properties to the instance of the grid property on the created object.
- rowIndices - ItemMapping<TNode,number>
- The mapping from a node to its row index. This option either sets the value directly or recursively sets properties to the instance of the rowIndices property on the created object.
- columnIndices - ItemMapping<TNode,number>
- The mapping from a node to its column index. This option either sets the value directly or recursively sets properties to the instance of the columnIndices property on the created object.
Properties
Gets or sets the mapping from a node to its column index.
Remarks
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.
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
Gets or sets the LayoutGrid.
Remarks
Examples
const row1 = gridData.grid.addRow()
const row2 = gridData.grid.addRow()
const column1 = gridData.grid.addColumn()
const column2 = gridData.grid.addColumn()
See Also
Gets or sets the mapping from nodes to LayoutGridCellDescriptors.
Remarks
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.
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
Gets or sets the mapping from a node to its row index.
Remarks
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.
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
Methods
combineWith
(data: LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>…) : LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>Combines this instance with the given layout data.
Remarks
Parameters
A map of options to pass to the method.
- data - LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>
- The LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel> to combine this instance with.
Returns
- ↪LayoutData<TNode,TEdge,TNodeLabel,TEdgeLabel>
- The combined layout data.