Row Data Sources
Controlled Data Source
The controlled data source provides fine-grained control over the rows displayed in Graphite Grid. Graphite Grid can be modeled using the controlled data source to match your row data exactly.
To use a controlled data source, set the rowDataSource
property on the grid
state to an object
of the form:
const source = {
kind: "controlled",
getRowCount: () => 10;
getRowNode: (p) => {
// return a row node
}
getRowById: (rowId) => {
// return a row node or null
}
}
The above form is the minimum required setup to create a controlled data source. The full functionality of the controlled data is explained below. However, see the Server Data Source guide for specific functionality related to server-side data loading.
Row Nodes
The controlled data source provided to the grid creates the row nodes provided to Graphite Grid. A RowNode is a description of the row to display in the grid. There are two types of RowNodes:
RowNodeLeaf
: used for rows that do not have a parent; these are the row nodes used when rows are not pivoted.RowNodeBranch
: used for rows that may have children rows. The children may be either aRowNodeLeaf
orRowNodeBranch
.
Row Node Leaf
The leaf node has the following type:
export interface RowNodeLeaf<T = unknown> {
readonly kind: "leaf";
readonly id: string;
readonly rowIndex: number | null;
readonly isLoading: boolean;
readonly hasError: boolean;
readonly context?: { [key: string]: unknown };
readonly data: T;
readonly parent: RowNodeBranch<T> | null;
readonly rowPin: RowPinType;
readonly editIndex: number | null;
}
- Name
kind
- Type
- string
- Description
The grid uses a string to determine the 'kind' of row node it is using.
- Name
id
- Type
- string
- Description
The unique identifier for the row.
- Name
rowIndex
- Type
- number | null
- Description
The row index of the row. This may be null as the grid can correctly place rows without it. However, populating this field where possible is highly recommended.
- Name
isLoading
- Type
- boolean
- Description
If the row is loading. It is useful when a row must be asynchronously loaded. The grid will be able to provide some feedback.
- Name
hasError
- Type
- boolean
- Description
If the row has an error. It helps indicate a row has an error (normally a data loading error). The reason for the error may be stored in the
context
field of the row or wherever works best for your application.
- Name
context
- Type
- { [key: string]: unknown }
- Description
A store for any additional data to associate with the row. Not used by Graphite Grid directly.
- Name
data
- Type
- T
- Description
The data associated with the row. This will be indexed by columns in the grid via the
field
property.
- Name
parent
- Type
- RowNodeBranch | null
- Description
The parent of this row. If the row is a child of a pivot, this property must be defined.
- Name
rowPin
- Type
- RowPinType
- Description
A meta value that provides information on whether the row is pinned to the top or bottom or is not pinned. Graphite Grid does not directly use this value and relies on the data source to determine which rows should be pinned on top and bottom.
- Name
editIndex
- Type
- number | null
- Description
The index to row data that this row belongs to when being edited. This property is useful when rows change order and can be edited. The edit index should refer to the original row index. This property is not required and can safely be omitted.
Best practice
Graphite Grid provides a utility function for creating leaf nodes:
import { createRowNodeLeaf } from "@1771technologies/graphite-grid-react"
const node = createRowNodeLeaf({ id: "<row-id>", data: ... })
Row Node Branch
The branch node has the following type:
export interface RowNodeBranch<T = unknown> {
readonly kind: "branch";
readonly id: string;
readonly rowIndex: number | null;
readonly isLoading: boolean;
readonly hasError: boolean;
readonly context?: { [key: string]: unknown };
readonly pivotKey: string;
readonly data: Record<string, unknown>;
readonly parent: RowNodeBranch<T> | null;
}
- Name
kind
- Type
- string
- Description
The grid uses a string to determine the 'kind' of row node it is using.
- Name
id
- Type
- string
- Description
The unique identifier for the row.
- Name
rowIndex
- Type
- number | null
- Description
The row index of the row. This may be
null
as the grid can correctly place rows without it. However, populating this field where possible is highly recommended.
- Name
isLoading
- Type
- boolean
- Description
If the row is loading. It is useful when a row must be asynchronously loaded. The grid will be able to provide some feedback.
- Name
hasError
- Type
- boolean
- Description
If the row has an error. It helps indicate a row has an error (normally a data loading error). The reason for the error may be stored in the
context
field of the row or wherever works best for your application.
- Name
context
- Type
- { [key: string]: unknown }
- Description
A store for any additional data to associate with the row. Not used by Graphite Grid directly.
- Name
pivotKey
- Type
- string
- Description
The pivot should be the value of the
rowPivotKey
for the branch of the row pivot model that this row represents.
- Name
data
- Type
- Record<string, unknown>
- Description
A key/value pair for the row branch. The key should be the
id
of a column. Unlike leaf nodes, the data for branch nodes is always indexed by the columnid
.
- Name
parent
- Type
- RowNodeBranch | null
- Description
The parent of this row. If the row is a child of a pivot, this property must be defined.
Basic Usage
An example of a controlled data source is shown below:
class ControlledSource implements RowDataSourceControlled<number[]> {
kind = "controlled" as const;
nodes: RowNodeLeaf<number[]>[];
lookup: Record<string, RowNodeLeaf<number[]>>;
constructor(data: number[][]) {
const nodes = data.map((d, i) =>
createRowNodeLeaf({
id: `${i}`,
data: d,
editIndex: i,
rowIndex: i,
}),
);
this.lookup = Object.fromEntries(nodes.map((node) => [node.id, node]));
this.nodes = nodes;
}
getRowCount = () => this.nodes.length;
getRowById = (id: string) => this.lookup[id] ?? null;
getRowNode = ({ rowIndex }: GetRowNodeParams<number[]>) => this.nodes[rowIndex];
}
export function ControlledDataSource() {
const grid = useGraphiteGrid({
initial: {
columnDefinitions: [
{ id: "Alpha", field: 0 },
{ id: "Beta", field: 1 },
{ id: "Stock Price", field: 2 },
{ id: "Gamma", field: 3 },
],
rowDataSource: new ControlledSource(data),
},
});
return (
<div style={{ height: 300 }}>
<GraphiteGridDom state={grid} />
</div>
);
}
A class has been used in the example above, but a plain JavaScript object
may also
be used. The controlled data source above is limited
and does not support all the grid functionality (such as
pivots, sorting, or filtering). See the Server Data Source
guide for a fully featured controlled data source.
Row Data Source Controlled Properties
Caution
Implementing a fully featured controlled data source is quite an involved task. Before doing so, it is worth considering whether the Client Data Source is sufficient for your use case.
The controlled data source has the following interface:
export interface RowDataSourceControlled<T = unknown> {
readonly kind: "controlled";
readonly init?: (api: GraphiteGridApi<T>) => void;
readonly getRowCount: () => number;
readonly getRowTopCount?: () => number;
readonly getRowBottomCount?: () => number;
readonly getRowNode: (params: GetRowNodeParams<T>) => RowNode<T>;
readonly getRowById: (rowId: string) => RowNode<T> | null;
readonly getAllRowIds?: () => Set<string>;
readonly getAllChildrenIdsForRow?: (rowId: string) => string[];
readonly getAllBranchIds?: (p: { api: GraphiteGridApi<T> }) => string[] | Promise<string[]>;
readonly getAllBranchIdsAtDepth?: (
params: GetAllBranchIdsAtDepth<T>,
) => string[] | Promise<string[]>;
readonly refresh?: (params: { api: GraphiteGridApi }) => void;
}
A full description of each of the controlled row data source properties is provided below:
- Name
kind
- Type
- "controlled"
- Description
A string indicating the type of data source. For a controlled data source, this must be "controlled".
- Name
init
- Type
- (api: GraphiteGridApi<T>) => void
- Description
A data source initialization function. Graphite Grid will call this function with the Grid API. This provides an opportunity to drive data fetching with the information provided by the grid API.
- Name
getRowCount
- Type
- () => number
- Description
A required callback that returns the current row count of the data source (excluding top and bottom frozen rows).
- Name
getRowTopCount
- Type
- () => number
- Description
An optional callback that returns the number of rows that should be frozen to the top of the grid.
- Name
getRowBottomCount
- Type
- () => number
- Description
An optional callback that returns the number of rows that should be frozen to the bottom of the grid.
- Name
getRowNode
- Type
- (params: GetRowNodeParams<T>) => RowNode<T>
- Description
A callback that returns a row node for a given row index. This property is required and should be as efficient as possible.
- Name
getRowById
- Type
- (rowId: string) => RowNode<T> | null
- Description
A callback that returns a row node for a given row
id
. It may returnnull
if the rowid
is not found.
- Name
getAllRowIds
- Type
- () => Set<string>
- Description
A callback that will return all the
id
s for rows. Necessary for supporting select all functionality. This property is optional.
- Name
getAllChildrenIdsForRow
- Type
- (rowId: string) => string[]
- Description
Returns the
id
s of a row's children (including branch nodes). This is required for row selection and to support group selection, but otherwise may be omitted.
- Name
getAllBranchIds
- Type
- (p: { api: GraphiteGridApi<T> }) => string[] | Promise<string[]>
- Description
Returns all the branch
id
s for the rows in the grid. This adds support for expanding all branch nodes in the grid.
- Name
getAllBranchIdsAtDepth
- Type
- (params: GetAllBranchIdsAtDepth<T>) => string[] | Promise<string[]>
- Description
Returns all the branch
id
s for the rows in the grid at a particular level. This is required to expand all the branch nodes at a particular level.
- Name
refresh
- Type
- (params: { api: GraphiteGridApi }) => void
- Description
Graphite Grid calls the
refresh
callback when the row data source needs to be updated. State changes, such as sort model or filter model changes, may require a view update.