RevoGrid uses a reactive store system to manage all data operations, including main data sources, pinned rows, column definitions, and data transformations. The store system provides real-time updates and efficient change detection.
Core data type definitions for grid data management.
/**
* Represents a single row of data in the grid
*/
type DataType<D = any> = {
[T in ColumnProp]: DataFormat<D>;
};
/**
* Data format for individual cell values
*/
type DataFormat<D = any> = any;
/**
* Column property type - string or number key
*/
type ColumnProp = string | number;
/**
* Row and column index types
*/
type RowIndex = number;
type ColIndex = number;Usage Example:
import { DataType, ColumnProp } from '@revolist/revogrid';
// Define strongly typed data
interface UserData {
id: number;
name: string;
email: string;
age: number;
}
const userData: DataType<UserData>[] = [
{ id: 1, name: 'John Doe', email: 'john@example.com', age: 30 },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 25 }
];State structure for managing data sources with virtualization and grouping support.
/**
* Data source state structure
*/
interface DataSourceState<T = DataType, ST = DimensionRows> {
/** Visible item indices for current viewport */
items: number[];
/** All item indices for maintaining order */
proxyItems: number[];
/** Actual data array */
source: T[];
/** Current grouping depth level */
groupingDepth: number;
/** Group data structure */
groups: Record<any, any>;
/** Dimension type (rgRow, rowPinStart, rowPinEnd) */
type: ST;
/** Trimmed/filtered items */
trimmed: Record<any, any>;
}Usage Example:
// Access data source state through providers
const providers = await grid.getProviders();
const dataProvider = providers.data;
// Get current data source state
const sourceStore = await grid.getSourceStore('rgRow');
sourceStore.onChange((state: DataSourceState) => {
console.log('Data changed:', state.source.length, 'items');
console.log('Visible items:', state.items.length);
});Service class for managing grid data sources and operations.
/**
* Data provider service for managing grid data
*/
interface DataProvider {
/**
* Set data source for specific dimension
* @param source - Data array
* @param type - Dimension type
* @param disableVirtual - Disable virtualization
*/
setData(source: DataType[], type: DimensionRows, disableVirtual?: boolean): void;
/**
* Update specific cell data
* @param details - Cell update details
* @param refresh - Whether to refresh view
*/
setCellData(details: SetCellData, refresh?: boolean): void;
/**
* Update range of data
* @param data - Range data to update
* @param type - Dimension type
*/
setRangeData(data: RangeUpdateData, type: DimensionRows): void;
/**
* Refresh data for specific dimension
* @param type - Dimension type to refresh
*/
refresh(type?: DimensionRows): void;
/**
* Change row order (drag and drop)
* @param details - Order change details
*/
changeOrder(details: RowOrderChangeDetails): void;
/**
* Set trimmed/hidden rows
* @param trimmed - Trimmed row configuration
* @param type - Dimension type
*/
setTrimmed(trimmed: Record<number, boolean>, type: DimensionRows): void;
}Usage Example:
// Get data provider from grid
const providers = await grid.getProviders();
const dataProvider = providers.data;
// Set new data
const newData = [
{ name: 'Alice', age: 28, email: 'alice@example.com' }
];
dataProvider.setData(newData, 'rgRow');
// Update single cell
dataProvider.setCellData({
row: 0,
col: 'age',
val: 29,
rowSource: 'rgRow'
});
// Refresh grid data
dataProvider.refresh('rgRow');Custom row properties and configurations.
/**
* Row definition for custom row properties
*/
interface RowDefinition {
/** Row type/dimension */
type: DimensionRows;
/** Row index */
index: number;
/** Custom row height */
size?: number;
/** Custom row CSS classes */
class?: string | Record<string, boolean>;
/** Custom row styles */
style?: Record<string, any>;
}Usage Example:
// Define custom row properties
grid.rowDefinitions = [
{
type: 'rgRow',
index: 0,
size: 50,
class: 'header-row',
style: { backgroundColor: '#f0f0f0' }
},
{
type: 'rgRow',
index: 5,
size: 80,
class: { 'important-row': true }
}
];Operations for updating and manipulating grid data.
/**
* Cell data update details
*/
interface SetCellData {
/** Row index */
row: number;
/** Column property */
col: ColumnProp;
/** New value */
val: any;
/** Row source dimension */
rowSource?: DimensionRows;
}
/**
* Range data update details
*/
interface RangeUpdateData {
/** Start cell coordinate */
start: Cell;
/** End cell coordinate */
end: Cell;
/** Update data array */
data: any[][];
}
/**
* Row order change details for drag and drop
*/
interface RowOrderChangeDetails {
/** Source row index */
from: number;
/** Target row index */
to: number;
/** Row dimension type */
type: DimensionRows;
}Usage Example:
// Update range of cells
const rangeUpdate: RangeUpdateData = {
start: { x: 0, y: 0 },
end: { x: 1, y: 1 },
data: [
['New Value 1', 'New Value 2'],
['New Value 3', 'New Value 4']
]
};
const providers = await grid.getProviders();
providers.data.setRangeData(rangeUpdate, 'rgRow');Reactive store system for real-time updates.
/**
* Observable interface for reactive state management
*/
interface Observable<T> {
/** Subscribe to state changes */
onChange(callback: (state: T) => void): () => void;
/** Get current state */
get(): T;
/** Update state */
set(state: T): void;
}
/**
* Store connector for accessing grid stores
*/
interface StoreConnector {
/** Get data source store */
getSourceStore(type?: DimensionRows): Observable<DataSourceState>;
/** Get column store */
getColumnStore(type?: DimensionCols): Observable<ColumnCollection>;
/** Get dimension store */
getDimensionStore(type?: DimensionRows | DimensionCols): Observable<DimensionSettingsState>;
/** Get viewport store */
getViewportStore(type?: DimensionRows | DimensionCols): Observable<ViewportState>;
}Usage Example:
// Subscribe to data changes
const sourceStore = await grid.getSourceStore('rgRow');
const unsubscribe = sourceStore.onChange((state) => {
console.log('Data updated:', state.source.length, 'items');
console.log('Groups:', Object.keys(state.groups).length);
});
// Clean up subscription
// unsubscribe();Managing pinned/sticky rows at top and bottom of grid.
/**
* Pinned row data sources
*/
interface PinnedRowSources {
/** Pinned top rows data */
pinnedTopSource: DataType[];
/** Pinned bottom rows data */
pinnedBottomSource: DataType[];
}Usage Example:
// Set pinned rows
grid.pinnedTopSource = [
{ name: 'TOTAL', amount: 1000, type: 'summary' }
];
grid.pinnedBottomSource = [
{ name: 'FOOTER', info: 'End of data', type: 'footer' }
];
// Access pinned row data
const pinnedTop = await grid.getSource('rowPinStart');
const pinnedBottom = await grid.getSource('rowPinEnd');Utilities for data validation and transformation before setting to grid.
/**
* Data validation result
*/
interface DataValidationResult {
/** Whether data is valid */
isValid: boolean;
/** Validation errors */
errors: string[];
/** Cleaned/transformed data */
data: DataType[];
}
/**
* Data transformation options
*/
interface DataTransformOptions {
/** Column mapping for property names */
columnMapping?: Record<string, ColumnProp>;
/** Type converters for data types */
typeConverters?: Record<ColumnProp, (val: any) => any>;
/** Default values for missing properties */
defaults?: Partial<DataType>;
}Usage Example:
// Transform raw data before setting to grid
const rawData = [
{ full_name: 'John Doe', user_age: '30', email_address: 'john@example.com' }
];
const transformOptions: DataTransformOptions = {
columnMapping: {
full_name: 'name',
user_age: 'age',
email_address: 'email'
},
typeConverters: {
age: (val) => parseInt(val, 10)
},
defaults: {
status: 'active'
}
};
// Apply transformation (custom utility function)
// const transformedData = transformData(rawData, transformOptions);
// grid.source = transformedData;Managing filtered and hidden rows in the grid.
/**
* Trimmed row configuration
*/
interface TrimmedRows {
/** Map of row index to visibility */
[index: number]: boolean;
}
/**
* Filter configuration for data trimming
*/
interface FilterConfig {
/** Column to filter */
column: ColumnProp;
/** Filter type */
type: 'contains' | 'equals' | 'greaterThan' | 'lessThan' | 'custom';
/** Filter value */
value: any;
/** Custom filter function */
customFilter?: (cellValue: any, filterValue: any) => boolean;
}Usage Example:
// Hide specific rows
const trimmedRows: TrimmedRows = {
2: true, // Hide row index 2
5: true, // Hide row index 5
8: true // Hide row index 8
};
grid.trimmedRows = trimmedRows;
// Or use the method
await grid.addTrimmed(trimmedRows, 'filter', 'rgRow');
// Get visible data (excluding trimmed)
const visibleData = await grid.getVisibleSource('rgRow');