1771 Technologies Logo

Row Data Sources

Client Data Source

The client data source should be used when the row data for the grid is available on the client. Client-side data is simple to use and supports all row functionality out of the box, making it an excellent choice when the size of your row data is relatively small or already available on the client.

Best practice

Prefer the client-side data source as the first option and only switch to the controlled data source if loading your row data into the UI takes too long.

Basic Usage

The simplest client-side data source is an object of the form:

const source = {
  kind: "client",
  data: [1, 2, 3, 4],
};

The kind property is necessary for Graphite Grid to treat the source as a client source. The data property is an array of arbitrary data for the grid to use.

// Define your row data
const data = [
  [0.23, -0.12, 150.3, 0.05],
  [0.45, 0.18, 152.75, 0.28],
  [-0.34, 0.03, 149.55, 0.15],
  [0.12, 0.22, 150.05, -0.12],
  [0.67, -0.14, 153.6, 0.32],
  [-0.25, 0.11, 151.25, -0.07],
  [0.58, 0.19, 152.85, 0.19],
  [-0.12, 0.33, 150.1, 0.11],
  [0.29, 0.24, 149.95, -0.22],
  [-0.55, -0.18, 150.75, 0.27],
];
 
export function ClientSideDataSource() {
  const grid = useGraphiteGrid({
    initial: {
      columnDefinitions: [
        { id: "Alpha", field: 0 },
        { id: "Beta", field: 1 },
        { id: "Stock Price", field: 2 },
        { id: "Gamma", field: 3 },
      ],
      // Create your client source
      rowDataSource: {
        kind: "client",
        data,
      },
      // other properties
    },
  });
 
  return (
    <div style={{ height: 300 }}>
      <GraphiteGridDom state={grid} />
    </div>
  );
}

Columns interact with the row data source via the field property. In the above example, the data provided to the grid is an array of arrays of numbers (number[][]). Each item in the array is a row in the grid, and each row is an array of numbers.

Since we are working with arrays of numbers, the column definitions define a field property as a number. This tells the grid that each column is indexed based on the array index of the field regarding the row data.

The length of the array determines the row count.

Top and Bottom Data

The client data source allows for pinning data to the top and bottom of the grid. Rows pinned to the top and bottom will be frozen in the viewport and remain visible regardless of the scroll position of the viewport.

Use the topData and bottomData properties of the client data source to specify the rows that should be pinned to the top and bottom of the grid.

const source = {
  kind: "client",
  data: [1, 2, 3, 4],
  topData: [0],
  bottomData: [5],
};

To learn more, please see the guide on Row Pinning.

Row Ids

Every row in Graphite Grid must have a unique id. Graphite Grid automatically generates the id for individual rows when using the client-side row data source. A rowIdCreator may be set on the client data source to override the default process.

const grid = useGraphiteGrid({
  initial: {
    rowDataSource: {
      kind: "client",
      data,
      rowIdCreator: ({ dataIndex, data }) => {
        return `${dataIndex}-${data?.join("/")}`;
      },
    },
  },
});
 
// ...

The row id has no visual impact on the grid but is used for grid functionality where uniquely identifying rows is required, such as Row Selection and Row Detail.

Caution

Calculating row ids can be tricky, so exercise caution when overriding the grid's default functionality. In particular, the grid's behavior when two or more rows have the same id is undefined and will result in unexpected behavior

Pivot Branch Delimiter and Splitting Row Branch Ids

When using row pivots, a row pivot key is created for each pivot (this is how the grid pivots data). When using the client-side data source, Graphite Grid will create unique row ids for pivot rows based on the concatenation of the row pivot keys for each row pivot. When concatenating the keys, Graphite Grid will use a default delimiter that is unlikely to clash with any ids. This delimiter may be overridden by providing a value for getRowBranchIdDelimiter to the client data source.

const source = {
  kind: "client",
  getRowBranchIdDelimiter: () => "/",
  // other props
};

Graphite Grid will split the concatenated id in some situations (for example, to determine select-all-rows functionality). Usually, the default split functionality works well, but this may also be overridden by providing a value for splitRowBranchIdPath:

const source = {
  kind: "client",
  splitRowBranchIdPath: (id) => id.split("+/+"),
  // other props
};

Danger

Overriding the getRowBranchIdDelimiter or splitRowBranchIdPath is seldom needed (if ever). Great caution should be taken when doing so.