1771 Technologies Logo

Pivoting

Column Pivoting

Column pivoting uses the values of cells in a particular column to create new columns. In Graphite Grid, column pivots are a separate set of column definitions that can be toggled on or off using the pivotModeIsOn property. However, the definitions are not provided directly to the grid but are created via the pivotColumnSource property.

The pivotColumnModel is used by Graphite Grid to determine which columns have been pivoted. Columns used in the pivotColumnModel must have the pivotColumnKey property set in their definition. Generally, for pivot columns to make sense, there should also be some measures used for the pivot. The measureModel is used by Graphite Grid to determine which columns should be used as measures for pivots.

In summary:

  • pivotModeIsOn: used to switch between column pivot mode and normal column display.
  • pivotColumnSource: used by Graphite Grid for the creation of pivot columns.
  • pivotColumnModel: determines which columns have been pivoted. These columns must have a pivotColumnKey defined in their definition.
  • measureModel: determines which columns should be used as measures for pivots.

These properties form the starting point for column pivots in Graphite Grid. A basic example is shown below:

export function ColumnPivotingBasic() {
  const grid = useGraphiteGrid({
    initial: {
      columnDefinitions: financeColumns,
      pivotColumnModel: ["exchange"],
      measureModel: ["volume"],
      pivotModeIsOn: true,
      pivotColumnSource: "client",
      baseColumnDefinition: {
        freeWidthRatio: 1,
      },
      rowDataSource: { kind: "client", data: financeData },
    },
  });
 
  return (
    <WindowContainer className="h-[400px]">
      <div className="border border-border h-full">
        <GraphiteGridDom state={grid} />
      </div>
    </WindowContainer>
  );
}

Tip

You may notice that row pivots are not required for column pivots. This is intentional. Column pivots may be defined arbitrarily (depending on the pivotColumnSource). The default "client" source creates new columns where the values are the constituent parts of a measure for a particular row.

The Pivot Column Source

The pivotColumnSource is required to create pivot column definitions. It may be one of the following:

  • "client": for use with a client row data source, Graphite Grid will use its default settings for creating column pivots.
  • pivotColumnSourceClient: allows you to modify the pivot columns generated by Graphite Grid when using client column pivots.
  • pivotColumnSourceControlledi: a controlled pivot column source that should return a set of pivot column definitions. Definitions may be returned asynchronously.
  • null: indicates a data set does not support column pivots.

Client Pivot Column Source

When the pivotColumnSource is set to "client", Graphite Grid will create its default pivotColumnSourceClient value for column pivots. This default will use the pivotColumnModel to generate pivot definitions, which is usually sufficient for client column pivoting.

Depending on the columns being pivoted, adjusting the columns created by Graphite Grid's client source is sometimes helpful. A pivotColumnSourceClient may be provided instead of the "client" value in such cases. The pivotColumnSourceClient has a postProcessColumnPivotDefinitions callback that may be used to alter the generated pivot column definitions. For example, we could omit the total column that is generated by pivots:

export function ColumnPivotingClient() {
  const grid = useGraphiteGrid({
    initial: {
      pivotColumnSource: {
        kind: "client",
        postProcessColumnPivotDefinitions: ({ definitions }) => {
          return definitions.filter((def) => !def.id.includes("total"));
        },
      },
      // other properties
    },
  });
 
  // ...
}

The postProcessColumnPivotDefinitions callback must return an array of Column Definitions. Furthermore, every pivot column must begin with a pivotColumnIdPrefix.

The pivotColumnIdPrefix is a prefix on every pivot column. Graphite Grid uses it to differentiate between pivot columns and normal columns. Graphite Grid uses a default value for this prefix, but the default may be changed by providing a value for the pivotColumnIdPrefix property on the grid state.

const grid = useGraphiteGrid({
  initial: {
    pivotColumnIdPrefix: "Pivot:",
    // other properties
  },
});

Controlled Pivot Column Source

The controlled pivot column source delegates full control of generating pivot column definitions to the column source. Unlike the "client" source, the controlled pivot column source can asynchronously generate pivot columns.

The example below shows a contrived example of a controlled pivot source. Notice the getColumnPivotDefinitions function is an async function - but it may also be a synchronous function if necessary. Furthermore, unlike the "client" source, how pivot columns are defined and created is entirely up to the source. Hence, a valid measure model is not required.

export function ControlledPivotColumnSource() {
  const grid = useGraphiteGrid({
    initial: {
      pivotColumnModel: ["exchange", "sector"],
      pivotModeIsOn: true,
      pivotColumnSource: {
        kind: "controlled",
        getColumnPivotDefinitions: async ({ api }) => {
          const model = api.getPivotColumnModel();
 
          const idPrefix = api.getPivotColumnIdPrefix();
          return model.map((id) => {
            const column = api.getColumnById(id)!;
 
            return {
              ...column,
              id: `${idPrefix}:${column.id}`,
              field: ({ data }) => `${data[id]}`.length,
            };
          });
        },
      },
    },
  });
 
  return (
    <div style={{ height: 400 }}>
      <GraphiteGridDom state={grid} />
    </div>
  );
}

Graphite Grid will call the getColumnPivotDefinitions whenever the following properties change:

  • pivotColumnSource
  • pivotColumnModel
  • rowDataSource
  • measureModel
  • markerColumnDefinition
  • markerColumnEnabled

Tip

The controlled pivot column source may load definitions asynchronously. Columns can be in a loading state. The arePivotcolumnsPending API method returns true whenever columns are pending. It can be used to display loading indicators.

Column Pivots and Row Pivots

The column definitions created via pivot columns work the same way as normal column definitions. Hence, row pivots with aggregations will work as expected.

export const columns: ColumnDefinition<any>[] = [
  { id: "exchange", rowPivotKey: "exchange", pivotColumnKey: "exchange" },
  { id: "symbol" },
  { id: "currency" },
  { id: "sector", rowPivotKey: "sector", pivotColumnKey: "sector" },
  { id: "industry" },
  { id: "price", aggregation: "sum", measure: "sum" },
  { id: "volume", aggregation: "avg", measure: "sum" },
];
 
export function ColumnPivotsWithRowPivots() {
  const grid = useGraphiteGrid({
    initial: {
      columnDefinitions: columns,
      pivotColumnModel: ["exchange"],
      rowPivotModel: ["sector"],
      measureModel: ["price"],
      pivotModeIsOn: true,
      pivotColumnSource: "client",
      // other props
    },
  });
 
  const isPivotModeOn = grid.api.useApiSlice((s) => s.isPivotModeOn());
 
  return (
    <div>
      <div>
        <button onClick={() => grid.api.togglePivotMode()}>
          Pivot Mode: {isPivotModeOn ? "Yes" : "No"}
        </button>
      </div>
      <div style={{ height: 400 }}>
        <GraphiteGridDom state={grid} />
      </div>
    </div>
  );
}
Previous
Row Pivoting