This example calculates and displays five different column summaries:
import{ HotTable }from'@handsontable/react';import{ registerAllModules }from'handsontable/registry';import'handsontable/dist/handsontable.full.min.css';// register Handsontable's modulesregisterAllModules();exportconstExampleComponent=()=>{return(<HotTablelicenseKey="non-commercial-and-evaluation"data={[[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],[null]]}colHeaders={['sum','min','max','count','average']}rowHeaders={true}columnSummary={[{sourceColumn:0,type:'sum',destinationRow:3,destinationColumn:0,// force this column summary to treat non-numeric values as numeric valuesforceNumeric:true},{sourceColumn:1,type:'min',destinationRow:3,destinationColumn:1},{sourceColumn:2,type:'max',destinationRow:3,destinationColumn:2},{sourceColumn:3,type:'count',destinationRow:3,destinationColumn:3},{sourceColumn:4,type:'average',destinationRow:3,destinationColumn:4}]}/>);};
Built-in summary functions
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.
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:
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.
columnSummary={[{sourceColumn:0,// set this column summary to only summarize rows with physical indexes 0-2, 4, and 6-8ranges:[[0,2],[4],[6,8]],},{sourceColumn:0,// set this column summary to only summarize rows with physical indexes 0-5ranges:[[0,5]],}]}
Step 3: Calculate your summary
Now, decide how you want to calculate your column summary.
columnSummary={[{sourceColumn:0,// set this column summary to return the sum all values in the summarized columntype:'sum',},{sourceColumn:1,// set this column summary to return the lowest value in the summarized columntype:'min',}]}
Step 4: Provide the destination cell's coordinates
To display your column summary result in a cell, provide the destination cell's coordinates.
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.
Step 5: Make room for the destination cell
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:
Add an empty row to the bottom of your grid (to avoid overwriting your existing rows).
Reverse row coordinates for your column summary (to always display your summary result at the bottom).
TIP
To reverse row coordinates for your column summary, set the reversedRowCoords option to true, and adjust the destinationRow coordinate.
import{ HotTable }from'@handsontable/react';import{ registerAllModules }from'handsontable/registry';import'handsontable/dist/handsontable.full.min.css';// register Handsontable's modulesregisterAllModules();exportconstExampleComponent=()=>{return(<HotTablelicenseKey="non-commercial-and-evaluation"data={[[1,2,3,4,5],[6,7,8,9,10],[11,12,13,14,15],// add an empty row[null]]}colHeaders={true}rowHeaders={true}columnSummary={[{sourceColumn:0,type:'sum',// for this column summary, count row coordinates backwardreversedRowCoords:true,// now, to always display this column summary in the bottom row,// set `destinationRow` to `0` (i.e. the last possible row)destinationRow:0,destinationColumn:0},{sourceColumn:1,type:'min',// for this column summary, count row coordinates backwardreversedRowCoords:true,// now, to always display this column summary in the bottom row,// set `destinationRow` to `0` (i.e. the last possible row)destinationRow:0,destinationColumn:1}]}/>);};
The example below sets up five different column summaries. To do this, it:
Defines a function named 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)
Sets Handsontable's columnSummary configuration option to a function that:
Iterates over visible columns
For each visible column, adds a column summary with a configuration
To display the column summaries in the empty row added by generateData, sets the reversedRowCoords option to true, and the destinationRow option to 0
import{ HotTable }from'@handsontable/react';import{ registerAllModules }from'handsontable/registry';import'handsontable/dist/handsontable.full.min.css';// register Handsontable's modulesregisterAllModules();exportconstExampleComponent=()=>{// generate an array of arrays with dummy numeric dataconstgenerateData=(rows =3, columns =7, additionalRows =true)=>{let counter =0;const array2d =[...newArray(rows)].map(_=>[...newArray(columns)].map(_=> counter++));// add an empty row at the bottom, to display column summariesif(additionalRows){
array2d.push([]);}return array2d;};return(<HotTable
licenseKey="non-commercial-and-evaluation"
data={generateData(5,5,true)}
height="auto"
rowHeaders={true}
colHeaders={['sum','min','max','count','average']}
columnSummary={function(){const configArray =[];const summaryTypes =['sum','min','max','count','average'];for(let i =0; i <this.hot.countCols(); i++){// iterate over visible columns// for each visible column, add a column summary with a configuration
configArray.push({sourceColumn: i,type: summaryTypes[i],// count row coordinates backwardreversedRowCoords:true,// display the column summary in the bottom row (because of the reversed row coordinates)destinationRow:0,destinationColumn: i,forceNumeric:true});}return configArray;}}/>);};
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:
columnSummary={[{sourceColumn:1,// set the `type` option to `'custom'`type:'custom',destinationRow:0,destinationColumn:5,reversedRowCoords:true}]}
In your column summary object, add your custom summary function:
columnSummary={[{type:'custom',destinationRow:0,destinationColumn:5,reversedRowCoords:true,// add your custom summary functioncustomFunction:function(endpoint){// implement your function here}}]}
This example implements a function that counts the number of even values in a column:
import{ HotTable }from'@handsontable/react';import{ registerAllModules }from'handsontable/registry';import'handsontable/dist/handsontable.full.min.css';// register Handsontable's modulesregisterAllModules();exportconstExampleComponent=()=>{// generate an array of arrays with dummy numeric dataconstgenerateData=(rows =3, columns =7, additionalRows =true)=>{let counter =0;const array2d =[...newArray(rows)].map(_=>[...newArray(columns)].map(_=> counter++));if(additionalRows){
array2d.push([]);
array2d.push([]);}return array2d;};return(<HotTable
licenseKey="non-commercial-and-evaluation"
data={generateData(5,7)}
height="auto"
colHeaders={true}
rowHeaders={true}
columnSummary={[// configure a column summary{// set the `type` option to `'custom'`type:'custom',destinationRow:0,destinationColumn:5,reversedRowCoords:true,// add your custom summary functioncustomFunction:function(endpoint){// implement a function that counts the number of even values in the columnconst hotInstance =this.hot;let evenCount =0;// a helper functionconstcheckRange=rowRange=>{let i = rowRange[1]|| rowRange[0];let counter =0;do{if(parseInt(hotInstance.getDataAtCell(i, endpoint.sourceColumn),10)%2===0){
counter++;}
i--;}while(i >= rowRange[0]);return counter;}// go through all declared rangesfor(const r in endpoint.ranges){if(endpoint.ranges.hasOwnProperty(r)){
evenCount +=checkRange(endpoint.ranges[r]);}}return evenCount;},forceNumeric:true}]}/>);};
Round a column summary result
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. For example:
import{ HotTable }from'@handsontable/react';import{ registerAllModules }from'handsontable/registry';import'handsontable/dist/handsontable.full.min.css';// register Handsontable's modulesregisterAllModules();exportconstExampleComponent=()=>{return(<HotTablelicenseKey="non-commercial-and-evaluation"data={[[0.5,0.5],[0.5,0.5],[1,1],[],[]]}colHeaders={true}rowHeaders={true}columnSummary={[{type:'average',destinationRow:0,destinationColumn:0,reversedRowCoords:true},{type:'average',destinationRow:0,destinationColumn:1,reversedRowCoords:true,// round this column summary result to two digits after the decimal pointroundFloat:2}]}/>);};
Deal with non-numeric values
To summarize a column that contains non-numeric data, you can:
Either force your column summary to treat non-numeric values as numeric values
Or throw an error whenever a non-numeric value is passed to your column summary
Or make your column summary skip any non-numeric values
Force numeric values
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:
import{ HotTable }from'@handsontable/react';import{ registerAllModules }from'handsontable/registry';import'handsontable/dist/handsontable.full.min.css';// register Handsontable's modulesregisterAllModules();exportconstExampleComponent=()=>{return(<HotTablelicenseKey="non-commercial-and-evaluation"data={[[0,1,2],['3c','4b',5],[],[]]}colHeaders={true}rowHeaders={true}columnSummary={[{type:'sum',destinationRow:0,destinationColumn:0,reversedRowCoords:true,// force this column summary to treat non-numeric values as numeric valuesforceNumeric:true},{type:'sum',destinationRow:0,destinationColumn:1,reversedRowCoords:true,// force this column summary to treat non-numeric values as numeric valuesforceNumeric:true}]}/>);};
Throw data type errors
You can throw a data type error whenever a non-numeric value is passed to your column summary.
import{ HotTable }from'@handsontable/react';import{ registerAllModules }from'handsontable/registry';import'handsontable/dist/handsontable.full.min.css';// register Handsontable's modulesregisterAllModules();exportconstExampleComponent=()=>{return(<HotTablelicenseKey="non-commercial-and-evaluation"data={[[0,1,2],['3c','4b',5],[],[]]}colHeaders={true}rowHeaders={true}columnSummary={[{type:'sum',destinationRow:0,destinationColumn:0,reversedRowCoords:true,// enable throwing data type errors for this column summarysuppressDataTypeErrors:false},{type:'sum',destinationRow:0,destinationColumn:1,reversedRowCoords:true,// enable throwing data type errors for this column summarysuppressDataTypeErrors:false}]}/>);};