1771 Technologies Logo

Rows

Row Sorting

The values of a particular column may sort rows if that column definition has a sortComparator defined. A sort may be ascending or descending.

The sortCycle property on the column definition determines the sort ordering of the column as the grid cycles through sorts for that column. The grid will move to the next sort each time a header cell is clicked.

export function RowSorting() {
  const grid = useGraphiteGrid({
    initial: {
      columnDefinitions: [
        { id: "Ticker Symbol", field: 0, sortComparator: "string" },
        { id: "Open Price", field: 1, sortComparator: "number" },
        { id: "Close Price", field: 2, sortComparator: "number" },
        { id: "Volume", field: 3, sortComparator: "number" },
        { id: "Market Cap", field: 4, sortComparator: "number" },
      ],
      sortModel: [{ columnId: "Open Price", isDescending: true }],
      // other props
    },
  });
 
  return (
    <div style={{ height: 300 }}>
      <GraphiteGridDom state={grid} />
    </div>
  );
}

Sort Model

Graphite Grid maintains a sort model to represent the grid sort state.

The sort model is an array of ColumnSort values, where a ColumnSort has the following type:

interface ColumnSort {
  readonly columnId: string; // the column being sorted
  readonly options?: ColumnSortOptions; // options applied to the sort
  readonly isDescending?: boolean; // true if the sort is descending
}

The model is represented as an array since multiple sorts may be applied. Sorts with a lower index in the array are given a higher priority. Sorting on multiple columns is only possible if the sortMultipleColumnsEnabled property is true. By default, it is false.

The ColumnSortOptions is used to adjust how a sort is applied. It has the following shape:

interface ColumnSortOptions {
  readonly isAccented?: boolean;
  readonly isAbsolute?: boolean;
  readonly nullsAppearFirst?: boolean;
}
  • isAccented: sorting should consider local characters for comparison results, e.g., aáàä are all the same.
  • isAbsolute: numbers should be sorted based on their magnitude, ignoring any sign value.
  • nullsAppearFirst: nulls should be the lowest possible value in a comparator.

Sort Comparators

The sortComparator property on a column definition determines how individual rows should be compared when a sort is applied to that column. Graphite Grid provides two sort comparators out of the box:

  • "string": useful for comparing textual data.
  • "number": useful for comparing numerical data.

The sortComparator property may also be a custom-defined function capable of comparing any type of data. The comparator function will be given the SortComparatorParams. An example date comparator is shown below:

import { nullComparator } from "@1771technologies/graphite-grid-react";
 
const dateComparator = <T>(params: SortComparatorParams<T>) => {
  const nullComparisonResult = nullComparator(params);
  if (nullComparisonResult !== 0) return nullComparisonResult;
 
  const left = new Date(params.left as string);
  const right = new Date(params.right as string);
 
  if (left < right) return -1;
  if (left > right) return 1;
  return 0;
};

Note the nullComparator provided by the Graphite Grid package. This comparator can correctly sort null values in data when creating a custom comparator. Once a custom comparator has been defined, it can be used on the column definition. For example:

export function RowSortingDateComparator() {
  const grid = useGraphiteGrid({
    initial: {
      columnDefinitions: [
        { id: "transaction_date", sortComparator: dateComparator },
        { id: "stock_market", sortComparator: "string" },
        { id: "ticker", sortComparator: "string" },
        { id: "price", sortComparator: "number" },
      ],
      sortModel: [{ columnId: "transaction_date", isDescending: false }],
      // other properties
    },
  });
 
  return (
    <div style={{ height: 300 }}>
      <GraphiteGridDom state={grid} />
    </div>
  );
}

Multi-Column Sort

Multi-column sort is enabled by setting the sortMultipleColumnsEnabled property to true on the grid state. This enables the ability to sort multiple columns through the grid. Sorts are added when a user holds the ctrl or cmd key and clicks to sort a column. Even if the sortMultipleColumnsEnabled is false, multiple-column sorts can still be applied using the Graphite Grid API.

export function RowSortingMultiple() {
  const grid = useGraphiteGrid({
    initial: {
      columnDefinitions: [
        { id: "Ticker Symbol", field: 0, sortComparator: "string" },
        { id: "Open Price", field: 1, sortComparator: "number" },
        { id: "Close Price", field: 2, sortComparator: "number" },
        { id: "Volume", field: 3, sortComparator: "number" },
        { id: "Market Cap", field: 4, sortComparator: "number" },
      ],
      sortMultipleColumnsEnabled: true,
      sortModel: [
        { columnId: "Ticker Symbol", isDescending: false },
        { columnId: "Open Price", isDescending: true },
      ],
      // other props
    },
  });
 
  return (
    <div style={{ height: 300 }}>
      <GraphiteGridDom state={grid} />
    </div>
  );
}

Sort Icon Renderer

Graphite Grid displays a sort icon in the column header when the column has a sort applied. The default icon can be replaced with a custom renderer using the headerSortIconRenderer property on the grid state.

export function SortIconRenderer() {
  const grid = useGraphiteGrid({
    initial: {
      headerSortIconRenderer: ({ sort }) => {
        // see https://heroicons.com/
        if (sort.isDescending) {
          return (
            <svg
              fill="none"
              viewBox="0 0 24 24"
              width={16}
              height={16}
              strokeWidth={1.5}
              stroke="currentColor"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M19.5 13.5 12 21m0 0-7.5-7.5M12 21V3"
              />
            </svg>
          );
        }
        if (!sort.isDescending) {
          return (
            <svg
              fill="none"
              viewBox="0 0 24 24"
              width={16}
              height={16}
              strokeWidth={1.5}
              stroke="currentColor"
            >
              <path
                strokeLinecap="round"
                strokeLinejoin="round"
                d="M4.5 10.5 12 3m0 0 7.5 7.5M12 3v18"
              />
            </svg>
          );
        }
 
        return null;
      },
      // other props
    },
  });
 
  // ...
}