How to render heatmap chart in Angular Pivot Table based on value cell selection?
Introduction
In data visualization, creating a heatmap chart based on selected value cells in a pivot table can present comparative data effectively. In this article, we will guide you through the process of rendering a heatmap chart based on value cells in a Angular Pivot Table.
Preventing heatmap chart rendering from header cell selection
To begin with, you need to ensure that the heatmap chart is rendered only when the value cells are selected. To prevent the heatmap chart from rendering when row and column headers are selected, use the cellSelecting event. This event is triggered before any cell selection happens in the pivot table. The code snippet below shows how to bind and define this event within the databound event:
[app.component.html]
<ejs-pivotview #pivotview id="PivotView" (dataBound)="onDataBound()">
</ejs-pivotview>
[app.component.ts]
onDataBound(): void {
// Here we bind 'cellSelecting' event
this.pivotObj.grid.cellSelecting = this.cellSelecting.bind(this);
}
cellSelecting(args: CellSelectingEventArgs) {
if (args.currentCell.classList.contains('e-rowsheader') ||
args.currentCell.classList.contains('e-columnsheader')) {
// Prevent Heatmap chart rendering when row or column headers are clicked
args.cancel = true;
}
}
In the above cellSelecting event, we checked whether the currently selected cell belongs to the row or column header by using their built-in class names (i.e., e-rowsheader
, e-columnsheader
). If the cell does indeed belong to these headers, we prevented the rendering of the heatmap chart by setting the args.cancel
property to true. This ensures that the heatmap chart is updated only when a value cell is selected.
Rendering the heatmap chart on value cell selection
To render the heatmap chart when a value cell is selected, you need to use the cellselected event with in your code. This event is triggered when a cell is selected in the pivot table, allowing you to render a heatmap chart based on the selected value cells.
[app.component.html]
<ejs-pivotview #pivotview id="PivotView" (cellSelected)="onCellSelected($event)">
</ejs-pivotview>
[app.component.ts]
onCellSelected(args: PivotCellSelectedEventArgs): void {
this.selectedCells = args.selectedCellsInfo;
if (this.selectedCells && this.selectedCells.length > 0 &&
(this.currentCell === undefined || (this.currentCell && this.currentCell.classList.contains('e-valuescontent')))) {
// Here we call the methods to render the heatmap chart only for value cells
this.frameSeries();
this.heatmapUpdate();
}
}
// Logic to frame the series for the heatmap chart
frameSeries(): void {
let columnGroupObject: { [key: string]: { x: string, y: number }[] } = {};
this.xLabels = [];
this.yLabels = [];
this.jsonDataSource = [];
for (let cell of this.selectedCells) {
if (cell.measure !== '') {
let columnSeries: string = (this.pivotObj.dataSourceSettings.values.length > 1 && this.measureList[cell.measure]) ?
(cell.columnHeaders.toString() + ' ~ ' + this.measureList[cell.measure]) : cell.columnHeaders.toString();
columnSeries = columnSeries == '' && cell.measure != '' ? 'Grand Total' : columnSeries;
let rHeaders: string = cell.rowHeaders == '' && cell.currentCell.axis != 'column' ? 'Grand Total' : cell.rowHeaders.toString();
if (columnGroupObject[columnSeries]) {
columnGroupObject[columnSeries].push({ x: rHeaders.toString(), y: Number(cell.value) });
} else {
columnGroupObject[columnSeries] = [{ x: rHeaders.toString(), y: Number(cell.value) }];
this.yLabels.push(columnSeries);
}
if (this.xLabels.indexOf(rHeaders.toString()) == -1) {
this.xLabels.push(rHeaders.toString());
}
}
}
for (let xcnt: number = 0; xcnt < this.xLabels.length; xcnt++) {
let xName: string = this.xLabels[xcnt];
let row: object = { 'xMember': xName };
for (let ycnt: number = 0; ycnt < this.yLabels.length; ycnt++) {
let YName: string = this.yLabels[ycnt];
let col: { x: string, y: number }[] = columnGroupObject[YName].filter(function (item) { return item.x == xName; });
(row as any)[YName] = col.length > 0 ? col[0].y : '';
}
this.jsonDataSource.push(row);
}
}
// Logic to update and render the heatmap chart
heatmapUpdate() {
if (this.onInit) {
this.onInit = false;
HeatMap.Inject(Adaptor, Legend, Tooltip);
this.heatmap = new HeatMap({
titleSettings: {
text: 'Sales Analysis'
},
legendSettings: {
position: 'Top',
visible: false,
},
xAxis: {
title: { text: this.pivotObj.dataSourceSettings.rows.map(function (args) { return args.caption || args.name; }).join(' ~ ') },
labels: this.xLabels,
labelIntersectAction: "Trim"
},
yAxis: {
title: { text: this.pivotObj.dataSourceSettings.values.map(function (args) { return args.caption || args.name; }).join(' ~ ') },
labels: this.yLabels,
},
dataSource: this.jsonDataSource,
dataSourceSettings: {
isJsonData: true,
adaptorType: 'Table',
xDataMapping: 'xMember',
},
load: (args: ILoadedEventArgs) => {
let selectedTheme: string = location.hash.split('/')[1];
selectedTheme = selectedTheme ? selectedTheme : 'Material';
args.heatmap.theme = <HeatMapTheme>(selectedTheme.charAt(0).toUpperCase() + selectedTheme.slice(1)).replace(/-dark/i, "Dark");
},
}, '#heatmap');
} else {
this.heatmap.dataSource = this.jsonDataSource;
this.heatmap.xAxis = {
title: { text: this.pivotObj.dataSourceSettings.rows.map(function (args) { return args.caption || args.name; }).join(' ~ ') },
labels: this.xLabels,
labelIntersectAction: "Trim"
};
this.heatmap.yAxis = {
title: { text: this.pivotObj.dataSourceSettings.values.map(function (args) { return args.caption || args.name; }).join(' ~ ') },
labels: this.yLabels
};
this.heatmap.refresh();
}
}
In the above-mentioned onCellSelected
method of the cellselected event, we ensure that the heatmap chart is only triggered for value cells in the pivot table. This is done by using the built-in class name associated with these value cells (i.e., e-valuesContent
). If the conditions are met, we proceed with the logic to frame the heatmap chart series by invoking the this.frameSeries()
and this.heatmapUpdate()
methods.
The following GIF image, which portrays the results of the above-mentioned snippets,
GIF
For a practical demonstration, refer to the sample of stackblitz.
Conclusion
I hope you enjoyed learning how to render a heatmap chart based on value cells in an Angular Pivot Table.
You can refer to our Angular Pivot Table feature tour page to learn about its other groundbreaking feature representations and documentation, and how to quickly get started for configuration specifications. You can also explore our Angular Pivot Table example to understand how to create and manipulate data.
For current customers, you can check out our components on the License and Downloads page. If you are new to Syncfusion, you can try our 30-day free trial to check out our other controls.
If you have any queries or require clarifications, please let us know in the comments section below. You can also contact us through our support forums, support portal, or feedback portal. We are always happy to assist you!