Nested Grid - Display Hierarchical Data
The Nested Grid allows you to display hierarchical data by embedding RevoGrids inside cells. This is particularly useful when you need to show detailed, structured data within a cell, such as project details, task lists, or any other nested data structure.
Live Demo
Here’s a live example showing how nested grids can be used to display project tasks, along with row expansion capabilities:
Row Expansion
The Nested Grid combined with the Row Expansion plugin to provide a more interactive experience. Row expansion allows users to expand a row to reveal additional details or nested grids.
Enabling Row Expansion
To enable row expansion, you can configure the grid as follows:
import { RowExpandPlugin } from '@revolist/revogrid-pro';
grid.plugins = [RowExpandPlugin];
Example Configuration
Here’s an example of how to set up row expansion with nested grids:
grid.columns = [ { prop: 'id', name: 'ID', expand: true }, // Enable row expansion for this column { prop: 'name', name: 'Name' }, { prop: 'details', name: 'Details', }];
// Additional configuration for row expansiongrid.additionalData = { rowExpand: { expandedRows: new Set([1]), // Example of expanded rows expandedRowHeight: 200, // Height for the expanded row // Hide expand toggle based on row data hideExpand: (rowIndex, model) => { // Example: Hide expand toggle for rows without tasks return !model.tasks || model.tasks.length === 0; }, template: (h, props) => { return h('revo-grid', { key: 'nested-grid', class: 'mt-1', style: { height: '100%', maxHeight: '90%', maxWidth: '95%', }, theme: isDark() ? 'darkCompact' : 'compact', resize: true, readonly: true, columns: [ { prop: 'id', name: '#', size: 50 }, { prop: 'task', name: 'Task', size: 220 }, { prop: 'status', name: 'Status', size: 150, cellProperties: ({ value }) => ({ style: { color: '#fff', backgroundColor: value === 'Complete' ? '#00c874' : value === 'In Progress' ? '#fdaa3d' : '#e2435c', }, }), }, ], source: props.model.tasks, // Source data for the nested grid hideAttribution: true, }); }, },};
Configuration Options
The nested grid configuration supports all standard RevoGrid properties. Here are some commonly used options:
columns
: Array of column definitions for the nested gridsource
: Function that returns the data array for the nested gridtheme
: Theme to apply to nested gridsreadonly
: Whether the nested grid should be read-onlyrowSize
: Height of rows in the nested gridresize
: Enable column resizing in nested grid- Any other RevoGrid properties you want to apply to nested grids
Row Expansion Options
The row expansion configuration supports several options to control expansion behavior:
expandedRows
: Set of row IDs that should be expanded by defaultexpandedRowHeight
: Height for expanded rows (in pixels)hideExpand
: Controls visibility of expand toggle buttons, can be:- A boolean:
true
to hide all expand toggles - A function:
(rowIndex: number, model: any) => boolean
for conditional control
- A boolean:
Example of conditional expand toggle visibility:
grid.additionalData = { rowExpand: { // Hide expand toggle for rows that don't have nested data hideExpand: (rowIndex, model) => { return !model.hasNestedData || model.tasks?.length === 0; }, // ... other configuration options }};
Best Practices
- Data Structure: Organize your data hierarchically with clear parent-child relationships.
- Performance: Consider the following for optimal performance:
- Limit the number of nested grids visible at once
- Keep nested data sets reasonably sized
- Use read-only mode for nested grids if editing isn’t required
- Responsive Design: Ensure columns with nested grids have sufficient width.
- User Experience: Use row expansion judiciously to enhance user interaction without overwhelming them with too much information at once.
Advanced Usage
Custom Cell Templates
You can combine nested grids with custom cell templates for rich data visualization:
{ prop: 'progress', name: 'Progress', cellTemplate: (h, props) => { const progress = props.model[props.prop] || 0; return h('div', { style: { width: '100%', height: '100%' } }, [ h('div', { style: { width: `${progress}%`, backgroundColor: progress === 100 ? '#4CAF50' : '#2196F3' } }) ]); }}