Custom aggregate in Vue Grid component
25 May 202416 minutes to read
The custom aggregate feature in Syncfusion’s Vue Grid component allows you to calculate aggregate values using your own aggregate function. This feature can be useful in scenarios where the built-in aggregate functions do not meet your specific requirements. To use the custom aggregate option, follow the steps below:
-
Set the type property to Custom in the e-aggregate -> e-column.
-
Provide your custom aggregate function in the customAggregate property.
The custom aggregate function will be invoked differently for total and group aggregations:
Total Aggregation: The custom aggregate function will be called with the whole dataset and the current aggregate column object as arguments.
Group Aggregation: The custom aggregate function will be called with the current group details and the aggregate column object as arguments.
Here’s an example that demonstrates how to use the custom aggregate feature in the Vue Grid component:
<template>
<div id="app">
<ejs-grid :dataSource='data' height='268px'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='right' width=120></e-column>
<e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
<e-column field='Freight' format='C2' width=150></e-column>
<e-column field='ShipCountry' headerText='Ship Country' width=150></e-column>
</e-columns>
<e-aggregates>
<e-aggregate>
<e-columns>
<e-column columnName="ShipCountry" type="Custom" :customAggregate="customAggregateFn" :footerTemplate='footerTemplate'></e-column>
</e-columns>
</e-aggregate>
</e-aggregates>
</ejs-grid>
</div>
</template>
<script setup>
import { provide, createApp } from "vue";
import { GridComponent as EjsGrid, ColumnsDirective as EColumns, ColumnDirective as EColumn, Aggregate } from "@syncfusion/ej2-vue-grids";
import { data } from './datasource.js';
const app = createApp();
footerTemplate: function () {
return { template : app.component('footerTemplate', {
template: `<span>Brazil Count: {{data.Custom}}</span>`,
data () {return { data: {}};}
})
}
}
customAggregateFn : function (data) {
return data.result.filter((item) => item.ShipCountry === 'Brazil').length;
}
provide('grid', [Aggregate]);
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-vue-buttons/styles/tailwind.css";
</style><template>
<div id="app">
<ejs-grid :dataSource='data' height='268px'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='right' width=120></e-column>
<e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
<e-column field='Freight' format='C2' width=150></e-column>
<e-column field='ShipCountry' headerText='Ship Country' width=150></e-column>
</e-columns>
<e-aggregates>
<e-aggregate>
<e-columns>
<e-column columnName="ShipCountry" type="Custom" :customAggregate="customAggregateFn" :footerTemplate='footerTemplate'></e-column>
</e-columns>
</e-aggregate>
</e-aggregates>
</ejs-grid>
</div>
</template>
<script>
import { GridComponent, ColumnsDirective, ColumnDirective, Aggregate } from "@syncfusion/ej2-vue-grids";
import { data } from './datasource.js';
import { provide, createApp } from "vue";
const app = createApp();
export default {
name: "App",
components: {
"ejs-grid":GridComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective,
"e-aggregates":AggregatesDirective,
"e-aggregate":AggregateDirective
},
data() {
return {
data: data,
footerTemplate: function () {
return { template : app.component('footerTemplate', {
template: `<span>Brazil Count: {{data.Custom}}</span>`,
data () {return { data: {}};}
})
}
}
};
},
methods: {
customAggregateFn : function (data) {
return data.result.filter((item) => item.ShipCountry === 'Brazil').length;
}
},
provide("grid", [Aggregate]);
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-vue-buttons/styles/tailwind.css";
</style>To access the custom aggregate value inside template, use the key as
Custom.
Show the count of distinct values in aggregate row
You can calculate the count of distinct values in an aggregate row by using custom aggregate functions. By specifying the type as Custom and providing a custom aggregate function in the customAggregate property, you can achieve this behavior.
Here’s an example that demonstrates how to show the count of distinct values for the ShipCountry column using a custom aggregate.
<template>
<div id="app">
<ejs-grid :dataSource='data' height='268px'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='right' width=120></e-column>
<e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
<e-column field='Freight' format='C2' width=150></e-column>
<e-column field='ShipCountry' headerText='Ship Country' width=150></e-column>
</e-columns>
<e-aggregates>
<e-aggregate>
<e-columns>
<e-column columnName="ShipCountry" type="Custom" :customAggregate="customAggregateFn" :footerTemplate='footerTemp'></e-column>
</e-columns>
</e-aggregate>
</e-aggregates>
</ejs-grid>
</div>
</template>
<script setup>
import { provide, createApp } from "vue";
import { GridComponent as EjsGrid, ColumnsDirective as EColumns, ColumnDirective as EColumn, Aggregate } from "@syncfusion/ej2-vue-grids";
import { DataUtil } from '@syncfusion/ej2-data';
import { data } from './datasource.js';
const app = createApp();
const footerTemp = function () {
return { template : app.component('footerTemplate', {
template: `<span>Distinct Count: {{data.Custom}}</span>`,
data () {return { data: {}};}
})
}
}
const customAggregateFn = function () {
const distinct = DataUtil.distinct(this.data, 'ShipCountry', true);
return distinct.length;
}
provide('grid', [Aggregate]);
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-vue-buttons/styles/tailwind.css";
</style><template>
<div id="app">
<ejs-grid :dataSource='data' height='268px'>
<e-columns>
<e-column field='OrderID' headerText='Order ID' textAlign='right' width=120></e-column>
<e-column field='CustomerID' headerText='Customer ID' width=150></e-column>
<e-column field='Freight' format='C2' width=150></e-column>
<e-column field='ShipCountry' headerText='Ship Country' width=150></e-column>
</e-columns>
<e-aggregates>
<e-aggregate>
<e-columns>
<e-column columnName="ShipCountry" type="Custom" :customAggregate="customAggregateFn" :footerTemplate='footerTemp'></e-column>
</e-columns>
</e-aggregate>
</e-aggregates>
</ejs-grid>
</div>
</template>
<script>
import { GridComponent, ColumnDirective, ColumnsDirective, Aggregate } from "@syncfusion/ej2-vue-grids";
import { DataUtil } from '@syncfusion/ej2-data';
import { data } from './datasource.js';
export default {
name: "App",
components: {
"ejs-grid":GridComponent,
"e-columns":ColumnsDirective,
"e-column":ColumnDirective,
"e-aggregates":AggregatesDirective,
"e-aggregate":AggregateDirective
},
data() {
return {
data: data,
footerTemp: function () {
return { template : Vue.component('footerTemplate', {
template: `<span>Distinct Count: {{data.Custom}}</span>`,
data () {return { data: {}};}
})
}
}
};
},
methods: {
customAggregateFn: function () {
const distinct = DataUtil.distinct(this.data, 'ShipCountry', true);
return distinct.length;
}
},
provide: {
grid: [Aggregate]
}
}
</script>
<style>
@import "../node_modules/@syncfusion/ej2-base/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-buttons/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-calendars/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-dropdowns/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-inputs/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-navigations/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-popups/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-splitbuttons/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-vue-grids/styles/tailwind.css";
@import "../node_modules/@syncfusion/ej2-vue-buttons/styles/tailwind.css";
</style>