docs/content/guides/columns/column-summary/column-summary.md
Calculate sum, min, max, count, average or custom aggregates of individual columns' data, using Handsontable's aggregate functions.
[[toc]]
The ColumnSummary plugin lets you quickly calculate and display a column summary.
To customize your column summaries, you can:
This example calculates and displays five different column summaries:
::: only-for javascript
::: example #example1 --js 1 --ts 2
:::
:::
::: only-for react
::: example #example1 :react --js 1 --ts 2
:::
:::
::: only-for angular
::: example #example1 :angular --ts 1 --html 2
:::
:::
To decide how a column summary is calculated, you can use one of the following summary functions:
| Function | Description |
|---|---|
sum | Returns the sum of all values in a column. |
min | Returns the lowest value in a column. |
max | Returns the highest value in a column. |
count | Returns the number of all non-empty cells in a column. |
average | Returns the sum of all values in a column, |
| divided by the number of non-empty cells in that column. | |
custom | Lets you implement a custom summary function. |
You can customize each of your column summaries with configuration options.
For the full list of available options, see the API reference.
To set up a column summary, follow the steps below.
ColumnSummary pluginTo enable the ColumnSummary plugin, set the columnSummary configuration option to an array of objects. Each object represents a single column summary.
::: only-for javascript
import Handsontable from 'handsontable/base';
import { registerAllModules } from 'handsontable/registry';
// Register all Handsontable's modules.
registerAllModules();
const hot = new Handsontable(document.querySelector('#example'), {
licenseKey: 'non-commercial-and-evaluation',
data: [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]
],
colHeaders: true,
rowHeaders: true,
// set the `columnSummary` configuration option to an array of
// objects
columnSummary: [
{},
{}
],
});
:::
::: only-for react
import { HotTable } from '@handsontable/react-wrapper';
import { registerAllModules } from 'handsontable/registry';
// register Handsontable's modules
registerAllModules();
const ExampleComponent = () => {
return (
<HotTable
autoWrapRow={true}
autoWrapCol={true}
licenseKey="non-commercial-and-evaluation"
data={[
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15]
]}
colHeaders={true}
rowHeaders={true}
columnSummary={[
{},
{}
]}
/>
);
};
:::
::: only-for angular
import { GridSettings, HotTableModule } from "@handsontable/angular-wrapper";
const data = [
[1, 2, 3, 4, 5],
[6, 7, 8, 9, 10],
[11, 12, 13, 14, 15],
];
const configurationOptions: GridSettings = {
licenseKey: "non-commercial-and-evaluation",
colHeaders: true,
rowHeaders: true,
// set the `columnSummary` configuration option to an array of objects
columnSummary: [{}, {}],
};
<hot-table [data]="data" [settings]="configurationOptions"></hot-table>
:::
You can also set the columnSummary option to a function.
By default, a column summary takes all cells of the column in which it displays its result (see the destinationColumn option in step 4).
To summarize any other column, use the sourceColumn option:
::: only-for javascript
columnSummary: [
{
// set this column summary to summarize the first column
// (i.e. a column with physical index `0`)
sourceColumn: 0,
},
{
// set this column summary to summarize the second column
// (i.e. a column with physical index `1`)
sourceColumn: 1,
}
]
:::
::: only-for react
columnSummary={[
{
// set this column summary to summarize the first column
// (i.e. a column with physical index `0`)
sourceColumn: 0,
},
{
// set this column summary to summarize the second column
// (i.e. a column with physical index `1`)
sourceColumn: 1,
}
]}
:::
::: only-for angular
columnSummary: [
{
// set this column summary to summarize the first column
// (i.e. a column with physical index `0`)
sourceColumn: 0,
},
{
// set this column summary to summarize the second column
// (i.e. a column with physical index `1`)
sourceColumn: 1,
},
];
:::
You can also summarize individual ranges of rows (rather than a whole column). To do this, set the ranges option to an array of arrays, where each array represents a single row range.
::: only-for javascript
columnSummary: [
{
sourceColumn: 0,
// set this column summary to only summarize rows with physical
// indexes 0-2, 4, and 6-8
ranges: [
[0, 2], [4], [6, 8]
],
},
{
sourceColumn: 0,
// set this column summary to only summarize rows with physical
// indexes 0-5
ranges: [
[0, 5]
],
}
]
:::
::: only-for react
columnSummary={[
{
sourceColumn: 0,
// set this column summary to only summarize rows with physical
// indexes 0-2, 4, and 6-8
ranges: [
[0, 2], [4], [6, 8]
],
},
{
sourceColumn: 0,
// set this column summary to only summarize rows with physical
// indexes 0-5
ranges: [
[0, 5]
],
}
]}
:::
::: only-for angular
columnSummary: [
{
sourceColumn: 0,
// set this column summary to only summarize rows with physical
// indexes 0-2, 4, and 6-8
ranges: [[0, 2], [4], [6, 8]],
},
{
sourceColumn: 0,
// set this column summary to only summarize rows with physical
// indexes 0-5
ranges: [[0, 5]],
},
];
:::
Now, decide how you want to calculate your column summary.
You can:
::: only-for javascript
columnSummary: [
{
sourceColumn: 0,
// set this column summary to return the sum all values in the
// summarized column
type: 'sum',
},
{
sourceColumn: 1,
// set this column summary to return the lowest value in the
// summarized column
type: 'min',
},
];
:::
::: only-for react
columnSummary={[
{
sourceColumn: 0,
// set this column summary to return the sum all values in the
// summarized column
type: 'sum',
},
{
sourceColumn: 1,
// set this column summary to return the lowest value in the
// summarized column
type: 'min',
}
]}
:::
::: only-for angular
columnSummary: [
{
sourceColumn: 0,
// set this column summary to return the sum all values in the
// summarized column
type: "sum",
},
{
sourceColumn: 1,
// set this column summary to return the lowest value in the
// summarized column
type: "min",
},
];
:::
To display your column summary result in a cell, provide the destination cell's coordinates.
Set the destinationRow and destinationColumn options to the physical coordinates of your required cell.
::: only-for javascript
columnSummary: [
{
sourceColumn: 0,
type: 'sum',
// set this column summary to display its result in cell (4, 0)
destinationRow: 4,
destinationColumn: 0,
},
{
sourceColumn: 1,
type: 'min',
// set this column summary to display its result in cell (4, 1)
destinationRow: 4,
destinationColumn: 1
}
]
:::
::: only-for react
columnSummary={[
{
sourceColumn: 0,
type: 'sum',
// set this column summary to display its result in cell (4, 0)
destinationRow: 4,
destinationColumn: 0
},
{
sourceColumn: 1,
type: 'min',
// set this column summary to display its result in cell (4, 1)
destinationRow: 4,
destinationColumn: 1
}
]}
:::
::: only-for angular
columnSummary: [
{
sourceColumn: 0,
type: "sum",
// set this column summary to display its result in cell (4, 0)
destinationRow: 4,
destinationColumn: 0,
},
{
sourceColumn: 1,
type: "min",
// set this column summary to display its result in cell (4, 1)
destinationRow: 4,
destinationColumn: 1,
},
];
:::
::: tip
Don't change the className metadata of the summary row.
If you need to style the summary row, use the class name assigned automatically by the ColumnSummary plugin: columnSummaryResult.
:::
The ColumnSummary plugin doesn't automatically add new rows to display its summary results.
So, if you always want to display your column summary result below your existing rows, you need to:
::: tip
To reverse row coordinates for your column summary, set the reversedRowCoords option to true, and adjust the destinationRow coordinate.
:::
::: only-for javascript
::: example #example2 --js 1 --ts 2
:::
:::
::: only-for react
::: example #example2 :react --js 1 --ts 2
:::
:::
::: only-for angular
::: example #example2 :angular --ts 1 --html 2
:::
:::
Instead of setting up the column summary options manually, you can provide the whole column summary configuration as a function that returns a required array of objects.
The example below sets up five different column summaries. To do this, it:
generateData which generates an array of arrays with dummy numeric data, and which lets you add an empty row at the bottom of the grid (to make room for displaying column summaries)columnSummary configuration option to a function that:
- Iterates over visible columns
generateData, sets the reversedRowCoords option to true, and the destinationRow option to 0::: only-for javascript
::: example #example7 --js 1 --ts 2
:::
:::
::: only-for react
::: example #example7 :react --js 1 --ts 2
:::
:::
::: only-for angular
::: example #example3 :angular --ts 1 --html 2
:::
:::
Using a function to provide a column summary configuration lets you set up all sorts of more complex column summaries. For example, you can sum subtotals for nested groups:
::: only-for javascript
::: example #example8 --js 1 --ts 2
:::
:::
::: only-for react
::: example #example8 :react --js 1 --ts 2
:::
:::
::: only-for angular
::: example #example4 :angular --ts 1 --html 2
:::
:::
Apart from using the built-in summary functions, you can also implement your own custom function that performs any summary calculation you want.
To implement a custom summary function:
type option to 'custom':::: only-for javascript
columnSummary: [{
sourceColumn: 1,
// set the `type` option to `'custom'`
type: 'custom',
destinationRow: 0,
destinationColumn: 5,
reversedRowCoords: true
}]
:::
::: only-for react
columnSummary={[{
sourceColumn: 1,
// set the `type` option to `'custom'`
type: 'custom',
destinationRow: 0,
destinationColumn: 5,
reversedRowCoords: true
}]}
:::
::: only-for angular
columnSummary: [
{
sourceColumn: 1,
// set the `type` option to `'custom'`
type: "custom",
destinationRow: 0,
destinationColumn: 5,
reversedRowCoords: true,
},
];
:::
::: only-for javascript
columnSummary: [{
type: 'custom',
destinationRow: 0,
destinationColumn: 5,
reversedRowCoords: true,
// add your custom summary function
customFunction: function(endpoint) {
// implement your function here
}
}]
:::
::: only-for react
columnSummary={[{
type: 'custom',
destinationRow: 0,
destinationColumn: 5,
reversedRowCoords: true,
// add your custom summary function
customFunction: function(endpoint) {
// implement your function here
}
}]}
:::
::: only-for angular
columnSummary: [
{
type: "custom",
destinationRow: 0,
destinationColumn: 5,
reversedRowCoords: true,
// add your custom summary function
customFunction: function (endpoint) {
// implement your function here
},
},
];
:::
This example implements a function that counts the number of even values in a column:
::: only-for javascript
::: example #example9 --js 1 --ts 2
:::
:::
::: only-for react
::: example #example9 :react --js 1 --ts 2
:::
:::
::: only-for angular
::: example #example5 :angular --ts 1 --html 2
:::
:::
You can round a column summary result to a specific number of digits after the decimal point.
To enable this feature, set the roundFloat option to your preferred number of digits between 0 and 100.
See the following example:
::: only-for javascript
::: example #example12 --js 1 --ts 2
:::
:::
::: only-for react
::: example #example12 :react --js 1 --ts 2
:::
:::
::: only-for angular
::: example #example6 :angular --ts 1 --html 2
:::
:::
The roundFloat option accepts the following values:
| Value | Behavior |
|---|---|
false (default) | Don't round the column summary result. |
true | Round the result to 0 digits after the decimal point. |
| Integer 0-100 (n) | Round the result to n digits after the decimal point. |
| Integer < 0 | Round the result to 0 digits after the decimal point. |
| Integer > 100 | Round the result to 100 digits after the decimal point. |
'auto' | Automatically adjust the number of digits after the decimal point so the entire number fits into 8 digits. |
If you enable roundFloat, the data type returned by Handsontable's data-retrieving methods
(like getDataAtCell()) changes from number to string.
To summarize a column that contains non-numeric data, you can:
You can force your column summary to treat non-numeric values as numeric values.
::: tip
The forceNumeric option uses JavaScript's parseFloat() function.
This means that e.g., 3c is treated as 3, but c3 is still treated as c3.
:::
To enable this feature, set the forceNumeric option to true (by default, forceNumeric is set to false). For example:
::: only-for javascript
::: example #example10 --js 1 --ts 2
:::
:::
::: only-for react
::: example #example10 :react --js 1 --ts 2
:::
:::
::: only-for angular
::: example #example7 :angular --ts 1 --html 2
:::
:::
You can throw a data type error whenever a non-numeric value is passed to your column summary.
To throw data type errors, set the suppressDataTypeErrors option to false (by default, suppressDataTypeErrors is set to true). For example:
::: only-for javascript
::: example #example11 --js 1 --ts 2
:::
:::
::: only-for react
::: example #example11 :react --js 1 --ts 2
:::
:::
::: only-for angular
::: example #example8 :angular --ts 1 --html 2
:::
:::