Aggregates
Pantanal Grid supports aggregate calculations (sum, avg, min, max, count) displayed in group footers or column footers.
Basic Aggregates
Calculate sum, average, and count for numeric fields.
Group Footers with Aggregates
Display aggregates in group footer rows when using grouping.
Custom Group Footer Templates
Customize how aggregates are displayed using templates.
All Aggregate Types
Showing only Sum in the table footer. Other aggregates can be displayed outside the table.
Exemplo Traduzido (Português)
Labels dos aggregates traduzidos automaticamente conforme o locale.
Basic Aggregates
Calculate aggregates for numeric fields:
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef, type AggregateName } from '@pantanal/grid'
const rows = ref([
{ id: 1, name: 'Product A', price: 99.99, stock: 50 },
{ id: 2, name: 'Product B', price: 49.99, stock: 100 },
{ id: 3, name: 'Product C', price: 19.99, stock: 25 }
])
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80 },
{ field: 'name', title: 'Name' },
{ field: 'price', title: 'Price', format: (v: number) => `$${v.toFixed(2)}` },
{ field: 'stock', title: 'Stock' }
]
const aggregates: Record<string, AggregateName[]> = {
price: ['sum', 'avg'],
stock: ['sum'],
id: ['count']
}
</script>
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
:aggregates="aggregates"
/>
</template>Group Footers with Aggregates
Display aggregates in group footer rows:
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef, type GroupDescriptor, type AggregateName } from '@pantanal/grid'
const rows = ref([
{ id: 1, name: 'Product A', category: 'Electronics', price: 99.99, stock: 50 },
{ id: 2, name: 'Product B', category: 'Electronics', price: 49.99, stock: 100 },
{ id: 3, name: 'Product C', category: 'Clothing', price: 19.99, stock: 25 }
])
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80 },
{ field: 'name', title: 'Name' },
{ field: 'category', title: 'Category' },
{ field: 'price', title: 'Price', format: (v: number) => `$${v.toFixed(2)}` },
{ field: 'stock', title: 'Stock' }
]
const group = ref<GroupDescriptor[]>([
{ field: 'category', dir: 'asc' }
])
const aggregates: Record<string, AggregateName[]> = {
price: ['sum', 'avg'],
stock: ['sum'],
id: ['count']
}
</script>
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
:group="group"
:aggregates="aggregates"
:show-group-footers="true"
/>
</template>Custom Group Footer Templates
Customize how aggregates are displayed:
<script setup lang="ts">
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80 },
{ field: 'name', title: 'Name' },
{ field: 'category', title: 'Category' },
{
field: 'price',
title: 'Price',
aggregates: ['sum', 'avg'],
format: (v: number) => `$${v.toFixed(2)}`,
groupFooterTemplate: (group) => {
const priceAgg = group.aggregates?.price
if (priceAgg) {
const sum = priceAgg.sum ?? 0
const avg = priceAgg.avg ?? 0
return `<strong style="color: #3b82f6;">Total: $${sum.toFixed(2)} | Avg: $${avg.toFixed(2)}</strong>`
}
return ''
}
},
{
field: 'stock',
title: 'Stock',
aggregates: ['sum', 'min', 'max'],
groupFooterTemplate: (group) => {
const stockAgg = group.aggregates?.stock
if (stockAgg) {
return `Sum: ${stockAgg.sum} | Min: ${stockAgg.min} | Max: ${stockAgg.max}`
}
return ''
}
}
]
</script>Column-Level Aggregates
Define aggregates per column:
<script setup lang="ts">
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80 },
{ field: 'name', title: 'Name' },
{
field: 'price',
title: 'Price',
aggregates: ['sum', 'avg'], // Column-level aggregates
format: (v: number) => `$${v.toFixed(2)}`
},
{
field: 'stock',
title: 'Stock',
aggregates: ['sum', 'min', 'max']
}
]
</script>All Aggregate Types
Use all available aggregate functions:
<script setup lang="ts">
const aggregates: Record<string, AggregateName[]> = {
price: ['sum', 'avg', 'min', 'max'],
stock: ['sum', 'avg', 'min', 'max', 'count'],
id: ['count']
}
</script>Multi-Level Grouping with Aggregates
Aggregates work with multi-level grouping:
<script setup lang="ts">
const rows = ref([
{ id: 1, name: 'Product A', category: 'Electronics', brand: 'Brand X', price: 99.99, stock: 50 },
{ id: 2, name: 'Product B', category: 'Electronics', brand: 'Brand X', price: 49.99, stock: 100 },
{ id: 3, name: 'Product C', category: 'Electronics', brand: 'Brand Y', price: 19.99, stock: 25 },
{ id: 4, name: 'Product D', category: 'Clothing', brand: 'Brand X', price: 39.99, stock: 75 }
])
const group = ref<GroupDescriptor[]>([
{ field: 'category', dir: 'asc' },
{ field: 'brand', dir: 'asc' }
])
const aggregates: Record<string, AggregateName[]> = {
price: ['sum', 'avg'],
stock: ['sum'],
id: ['count']
}
</script>
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
:group="group"
:aggregates="aggregates"
:show-group-footers="true"
/>
</template>Column Footer Templates
Display aggregates in column footers (when not grouped):
<script setup lang="ts">
const columns: ColumnDef[] = [
{
field: 'price',
title: 'Price',
aggregates: ['sum', 'avg'],
format: (v: number) => `$${v.toFixed(2)}`,
footerTemplate: (aggregates) => {
const priceAgg = aggregates.price
if (priceAgg) {
const sum = priceAgg.sum ?? 0
const avg = priceAgg.avg ?? 0
return `<strong>Total: $${sum.toFixed(2)} | Avg: $${avg.toFixed(2)}</strong>`
}
return ''
}
}
]
</script>Complete Example
<script setup lang="ts">
import { ref } from 'vue'
import { PantanalGrid, type ColumnDef, type GroupDescriptor, type AggregateName } from '@pantanal/grid'
const rows = ref([
{ id: 1, name: 'Product A', category: 'Electronics', brand: 'Brand X', price: 99.99, stock: 50, units: 10 },
{ id: 2, name: 'Product B', category: 'Electronics', brand: 'Brand X', price: 49.99, stock: 100, units: 5 },
{ id: 3, name: 'Product C', category: 'Electronics', brand: 'Brand Y', price: 19.99, stock: 25, units: 20 },
{ id: 4, name: 'Product D', category: 'Clothing', brand: 'Brand X', price: 39.99, stock: 75, units: 15 },
{ id: 5, name: 'Product E', category: 'Clothing', brand: 'Brand Z', price: 29.99, stock: 200, units: 8 }
])
const columns: ColumnDef[] = [
{ field: 'id', title: 'ID', width: 80 },
{ field: 'name', title: 'Product Name' },
{ field: 'category', title: 'Category' },
{ field: 'brand', title: 'Brand' },
{
field: 'price',
title: 'Price',
aggregates: ['sum', 'avg'],
format: (v: number) => `$${v.toFixed(2)}`,
groupFooterTemplate: (group) => {
const priceAgg = group.aggregates?.price
if (priceAgg) {
return `Sum: $${(priceAgg.sum ?? 0).toFixed(2)} | Avg: $${(priceAgg.avg ?? 0).toFixed(2)}`
}
return ''
}
},
{
field: 'stock',
title: 'Stock',
aggregates: ['sum', 'min', 'max'],
groupFooterTemplate: (group) => {
const stockAgg = group.aggregates?.stock
if (stockAgg) {
return `Sum: ${stockAgg.sum} | Min: ${stockAgg.min} | Max: ${stockAgg.max}`
}
return ''
}
},
{
field: 'units',
title: 'Units',
aggregates: ['count'],
groupFooterTemplate: (group) => {
const unitsAgg = group.aggregates?.units
if (unitsAgg) {
return `Count: ${unitsAgg.count}`
}
return ''
}
}
]
const group = ref<GroupDescriptor[]>([
{ field: 'category', dir: 'asc' },
{ field: 'brand', dir: 'asc' }
])
const aggregates: Record<string, AggregateName[]> = {
price: ['sum', 'avg'],
stock: ['sum', 'min', 'max'],
units: ['count'],
id: ['count']
}
</script>
<template>
<PantanalGrid
:rows="rows"
:columns="columns"
key-field="id"
:group="group"
:aggregates="aggregates"
:show-group-footers="true"
locale="en"
responsive="table"
/>
</template>Aggregate Functions Reference
sum
Calculates the sum of all numeric values in a field.
const aggregates: Record<string, AggregateName[]> = {
price: ['sum']
}avg
Calculates the average (mean) of all numeric values in a field.
const aggregates: Record<string, AggregateName[]> = {
price: ['avg']
}min
Finds the minimum value in a field.
const aggregates: Record<string, AggregateName[]> = {
price: ['min']
}max
Finds the maximum value in a field.
const aggregates: Record<string, AggregateName[]> = {
price: ['max']
}count
Counts the number of items (works with any data type).
const aggregates: Record<string, AggregateName[]> = {
id: ['count']
}Use Cases
Financial Summary
const aggregates: Record<string, AggregateName[]> = {
revenue: ['sum'],
cost: ['sum'],
profit: ['sum', 'avg']
}Inventory Management
const aggregates: Record<string, AggregateName[]> = {
stock: ['sum', 'min', 'max'],
units: ['count'],
price: ['avg']
}Sales Analysis
const aggregates: Record<string, AggregateName[]> = {
sales: ['sum', 'avg'],
quantity: ['sum', 'count'],
price: ['min', 'max', 'avg']
}See Also
- Aggregates API - Complete API reference
- Grouping Guide - Grouping documentation
- Grouping Examples - More grouping examples