Customize cells elements in React Pivotview component
13 Sep 202524 minutes to read
You can customize each cell in the Pivot Table by using the cellTemplate
property. The cellTemplate
option accepts either an HTML string or the ID of an HTML element. You can use this to append extra HTML and show custom content or styles for every cell.
Implementation example
The following example demonstrates how to customize pivot table cells by displaying revenue trends with visual indicators. Each cell shows the actual value along with trend icons that represent performance direction.
import { PivotViewComponent } from '@syncfusion/ej2-react-pivotview';
import * as React from 'react';
import { renewableEnergy } from './datasource';
function App() {
function cellTemplate(props) {
return (<span className="tempwrap e-pivot-trend-neutral pv-icons"></span>);
}
let dataSourceSettings = {
dataSource: renewableEnergy,
expandAll: true,
enableSorting: true,
drilledMembers: [{ name: 'Year', items: ['FY 2015', 'FY 2017', 'FY 2018'] }],
formatSettings: [{ name: 'ProCost', format: 'C0' }],
rows: [
{ name: 'Year', caption: 'Production Year' }
],
columns: [
{ name: 'EnerType', caption: 'Energy Type' },
{ name: 'EneSource', caption: 'Energy Source' }
],
values: [
{ name: 'ProCost', caption: 'Revenue Growth' }
],
filters: []
};
let pivotObj;
return (<PivotViewComponent ref={d => pivotObj = d} id='PivotView' height={350} dataSourceSettings={dataSourceSettings} cellTemplate={cellTemplate.bind(this)} dataBound={trend.bind(this)}></PivotViewComponent>);
function trend() {
let cTable = [].slice.call(document.getElementsByClassName("e-table"));
let colLen = pivotObj.pivotValues[3].length;
let cLen = cTable[3].children[0].children.length;
let rLen = cTable[3].children[1].children.length;
let rowIndx;
for (let k = 0; k < rLen; k++) {
if (pivotObj.pivotValues[k] && pivotObj.pivotValues[k][0] !== undefined) {
rowIndx = (pivotObj.pivotValues[k][0]).rowIndex;
break;
}
}
let rowHeaders = [].slice.call(cTable[2].children[1].querySelectorAll('td'));
let rows = pivotObj.dataSourceSettings.rows;
if (rowHeaders.length > 1) {
for (let i = 0, Cnt = rows; i < Cnt.length; i++) {
let fields = {};
let fieldHeaders = [];
for (let j = 0, Lnt = rowHeaders; j < Lnt.length; j++) {
let header = rowHeaders[j];
if (header.className.indexOf('e-gtot') === -1 && header.className.indexOf('e-rowsheader') > -1 && header.getAttribute('fieldname') === rows[i].name) {
var headerName = rowHeaders[j].getAttribute('fieldname') + '_' + rowHeaders[j].textContent;
fields[rowHeaders[j].textContent] = j;
fieldHeaders.push(rowHeaders[j].textContent);
}
}
if (i === 0) {
for (let rnt = 0, Lnt = fieldHeaders; rnt < Lnt.length; rnt++) {
if (rnt !== 0) {
let row = fields[fieldHeaders[rnt]];
let prevRow = fields[fieldHeaders[rnt - 1]];
for (let j = 0, ci = 1; j < cLen && ci < colLen; j++, ci++) {
let node = cTable[3].children[1].children[row].childNodes[j];
let prevNode = cTable[3].children[1].children[prevRow].childNodes[j];
let ri = undefined;
let prevRi = undefined;
if (node) {
ri = node.getAttribute("index");
}
if (prevNode) {
prevRi = prevNode.getAttribute("index");
}
if (ri && ri < [].slice.call(pivotObj.pivotValues).length) {
if (pivotObj.pivotValues[prevRi][ci].value > pivotObj.pivotValues[ri][ci].value &&
node.querySelector('.tempwrap')) {
let trendElement = node.querySelector('.tempwrap');
trendElement.className = trendElement.className.replace('sb-icon-neutral', 'sb-icon-loss');
}
else if (pivotObj.pivotValues[prevRi][ci].value < pivotObj.pivotValues[ri][ci].value &&
node.querySelector('.tempwrap')) {
let trendElement = node.querySelector('.tempwrap');
trendElement.className = trendElement.className.replace('sb-icon-neutral', 'sb-icon-profit');
}
}
}
}
}
}
}
}
}
};
export default App;
import { IDataSet, Inject, PivotViewComponent } from '@syncfusion/ej2-react-pivotview';
import { DataSourceSettingsModel } from '@syncfusion/ej2-pivotview/src/model/datasourcesettings-model';
import * as React from 'react';
import { renewableEnergy } from './datasource';
function App() {
function cellTemplate(props): JSX.Element {
return (<span className="tempwrap e-pivot-trend-neutral pv-icons"></span>);
}
let dataSourceSettings: DataSourceSettingsModel = {
dataSource: renewableEnergy as IDataSet[],
expandAll: true,
enableSorting: true,
drilledMembers: [{ name: 'Year', items: ['FY 2015', 'FY 2017', 'FY 2018'] }],
formatSettings: [{ name: 'ProCost', format: 'C0' }],
rows: [
{ name: 'Year', caption: 'Production Year' }
],
columns: [
{ name: 'EnerType', caption: 'Energy Type' },
{ name: 'EneSource', caption: 'Energy Source' }
],
values: [
{ name: 'ProCost', caption: 'Revenue Growth' }
],
filters: []
}
let pivotObj: PivotViewComponent;
return (<PivotViewComponent ref={ (d: PivotViewComponent) => pivotObj = d } id='PivotView' height={350} dataSourceSettings={dataSourceSettings} cellTemplate={cellTemplate.bind(this)} dataBound={trend.bind(this)}></PivotViewComponent>);
function trend(): void {
let cTable: HTMLElement[] = [].slice.call(document.getElementsByClassName("e-table"));
let colLen: number = pivotObj.pivotValues[3].length;
let cLen: number = cTable[3].children[0].children.length;
let rLen: number = cTable[3].children[1].children.length;
let rowIndx: number;
for (let k: number = 0; k < rLen; k++) {
if (pivotObj.pivotValues[k] && pivotObj.pivotValues[k][0] !== undefined) {
rowIndx = ((pivotObj.pivotValues[k][0]) as IAxisSet).rowIndex;
break;
}
}
let rowHeaders: HTMLElement[] = [].slice.call(cTable[2].children[1].querySelectorAll('td'));
let rows: IFieldOptions[] = pivotObj.dataSourceSettings.rows as IFieldOptions[];
if (rowHeaders.length > 1) {
for (let i: number = 0, Cnt = rows; i < Cnt.length; i++) {
let fields: any = {};
let fieldHeaders: any = [];
for (let j: number = 0, Lnt = rowHeaders; j < Lnt.length; j++) {
let header: any = rowHeaders[j];
if (header.className.indexOf('e-gtot') === -1 && header.className.indexOf('e-rowsheader') > -1 && header.getAttribute('fieldname') === rows[i].name) {
var headerName = rowHeaders[j].getAttribute('fieldname') + '_' + rowHeaders[j].textContent;
fields[rowHeaders[j].textContent] = j;
fieldHeaders.push(rowHeaders[j].textContent);
}
}
if (i === 0) {
for (let rnt: number = 0, Lnt = fieldHeaders; rnt < Lnt.length; rnt++) {
if (rnt !== 0) {
let row: number = fields[fieldHeaders[rnt]];
let prevRow: number = fields[fieldHeaders[rnt - 1]];
for (let j: number = 0, ci = 1; j < cLen && ci < colLen; j++ , ci++) {
let node: HTMLElement = cTable[3].children[1].children[row].childNodes[j] as HTMLElement;
let prevNode: HTMLElement = cTable[3].children[1].children[prevRow].childNodes[j] as HTMLElement;
let ri: any = undefined;
let prevRi: any = undefined;
if (node) {
ri = node.getAttribute("index");
}
if (prevNode) {
prevRi = prevNode.getAttribute("index");
}
if (ri && ri < [].slice.call(pivotObj.pivotValues).length) {
if ((pivotObj.pivotValues[prevRi][ci] as IAxisSet).value > (pivotObj.pivotValues[ri][ci] as IAxisSet).value &&
node.querySelector('.tempwrap')) {
let trendElement: HTMLElement = node.querySelector('.tempwrap');
trendElement.className = trendElement.className.replace('sb-icon-neutral', 'sb-icon-loss');
} else if ((pivotObj.pivotValues[prevRi][ci] as IAxisSet).value < (pivotObj.pivotValues[ri][ci] as IAxisSet).value &&
node.querySelector('.tempwrap')) {
let trendElement: HTMLElement = node.querySelector('.tempwrap');
trendElement.className = trendElement.className.replace('sb-icon-neutral', 'sb-icon-profit');
}
}
}
}
}
}
}
}
}
};
export default App;