Skip to content

Instantly share code, notes, and snippets.

@davidnormo
Created February 27, 2023 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save davidnormo/d0121f8a512d6e1ff700bce67c91b52c to your computer and use it in GitHub Desktop.
Save davidnormo/d0121f8a512d6e1ff700bce67c91b52c to your computer and use it in GitHub Desktop.

Sorting Grouped Rows independently of Leaf Rows

Intro

Our users have many different uses of grids, using multiple row groups and sorts. It's been a long time want of our users to sort row groups in certain ways but unfortunately have been unable to do this successfully.

A specific scenario, using ag-grid's demo olympic dataset: There is a table of athletes, grouped by date, then grouped by country. We want to sort the country groups rows by total number of gold medals descending, sort the date group rows by their own date descending and finally sort the athlete (leaf) rows by total number of medals.

Current behaviour

Ag-grid supports sorting group rows but not independently of leaf nodes. Using sort in combination with rowGroup: true in the column def is enough to instruct ag-grid to sort the row groups when grouped by that column.

However there are some drawbacks to this:

  1. The row group column defs must appear first in the columnDefs array. One problem here is that this is an implicit API - it's not clear why columnDef ordering should effect row group sorting. Also I'm not sure if there would be any conflicts if using the same column multiple times.

  2. Using the shift + click UX a user needs to know to click the row groups first before selecting regular columns. Again this is an implied API - why would clicking the row groups first be necessary. Also it's not intuitive, user's have to learn or be taught this behaviour.

  3. If I want to sort a row group by a column then it has to be the same column used to sort the leaf rows. This is a deal breaker because we will want to sort row groups by any column independently of the leaf rows.

  4. There's no way to stack row group indexes. For example if we are sorting by column X, if 2 row groups have the same aggregated value of X then the user may want to choose column Y to sort additionally.

  5. There is also a bug (as of 28.2.1) where sorting row groups with a sortIndex also breaks. sortIndex on row groups need to be removed for any sorting to work correctly.

I can see where the current row group sorting behaviour has come from but it doesn't suit our use case. We have grids with multiple group rows and need to sort group rows in configurable ways alongside but independent of sorting leaf rows.

Proposal

We propose the following as a way of explicitly defining row group sorting behaviour independently of leaf rows in a backwards compatible way:

Below is an example snippet of some column definitions to produce the desired result detailed in the intro above. We introduce a new column property: sortRowGroupsBy

// column definitions...
{
  colId: 'country',
  field: 'country',
  rowGroup: true,

  // A new property to indicate that row groups of this column should be sorted by
  // the `total` column def (colId) then by the `gold` column def
  // (only applicable if column.rowGroup === true)
  sortRowGroupsBy: [
    ['gold', 'desc'],

    // Here a stacked sort: if two countries have the same number of golds it then sorts by total number of medals
    ['total', 'desc']
  ]
},
{
  colId: 'date',
  field: 'date'
  rowGroup: true,
  sortRowGroupsBy: [
    ['date', 'desc']
  ]
},
{
  field: 'total',
  // here `total` is not row grouped so this sort would apply to the leaf nodes
  sort: 'desc'
}

It's type may look like:

sortRowGroupsBy: SortDef[];

type SortDef = [ColId, SortDirection] | ColId
type ColId = string
type SortDirection = 'asc' | 'desc' | null

Detailed behaviour

  • sortRowGroupsBy is explicit in the following ways:
    • it sorts row groups - "does what is says on the tin"
    • defines the order of sorts (akin to sortIndex)
    • the direction of each sort (or the first defined by sortingOrder)
  • sortRowGroupsBy will only be applied to the grid if rowGroup: true is also set on the column, otherwise it can be ignored.
  • sortRowGroupsBy and sort can both be defined on the same column def to support sorting row groups and leaves by the same column.
  • sortRowGoupsBy should be seen as a stateful property and therefore should be got/set via columnApi.getColumnState and columnApi.applyColumnState. Alternatively via the get/set column group API.
  • There should be no change to the shift + click behaviour in order to maintain backwards compatibility. Configuring row group sorts can be defined in user land. However...
  • If sortRowGoupsBy is defined and a shift + click occurs on that column then:
    • a sort property doesn't need to be added as the sortRowGroupsBy should be used
    • the sortRowGroupsBy contents should be a single SortDef referencing itself and the direction set by the number of clicks (current behaviour)

Appendix

  1. Details of the current behaviour problems can be found in this support ticket: https://ag-grid.zendesk.com/hc/en-us/requests/25924?page=1

  2. There is some evidence of others ag-grid users who want this functionality: ag-grid/ag-grid#125

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment