ngx-modern-pivot-table
v1.0.3
Published
High-performance, lightweight, framework-agnostic pivot table engine with modern UI and Angular 18+ adapter. Zero jQuery dependency.
Maintainers
Readme
ngx-modern-pivot-table
A modern, high-performance, framework-agnostic pivot table engine with rich DOM rendering and a native Angular (16+) adapter. Zero jQuery dependency.
🚀 Key Features
- ⚡ Zero jQuery & Zero UI Framework Dependencies — pure TypeScript and standard modern DOM APIs.
- 📦 Ultra-Lightweight — ~10KB minified core vs ~270KB+ legacy jQuery pivot plugins.
- 🧩 Framework Agnostic Core — use standalone in Node.js, Vanilla JS, React, Vue, or Angular.
- 🅰️ Modern Angular Ivy Compatibility — Standalone component (
PivotTableComponent) and NgModule (NgxPivotTableModule) withOnPushchange detection. - 🔀 Interactive Header & Toolbar Sorting:
- Clickable Table Headers: Click row/col dimension headers to toggle Ascending (
A-Z ▴) and Descending (Z-A ▾). Click Total headers to sort by calculated values (Val ↑/Val ↓). - Interactive Toolbar Controls: Buttons (
Rows: ⇅ A-Z,Cols: ⇅ A-Z) cycle smoothly between label and value sort modes. - Two-Way Binding: Full
[(rowOrder)]and[(colOrder)]two-way binding support with internal change lock protection to prevent Angular parent reversion loops.
- Clickable Table Headers: Click row/col dimension headers to toggle Ascending (
- 🎛️ Full Interactive UI — native HTML5 Drag & Drop field pills, axis containers, aggregator selectors, metric selectors.
- 🔍 Attribute Filtering — popup modal with live search, Select All, Select None, and record counts.
- 🔢 Rich Aggregators — Sum, Count, Average, Min, Max, Median, Count Unique, List Unique, Variance, StdDev, and extensible custom aggregator registry.
- 🎨 Themeable & Responsive — CSS variable-driven styling with
default,dark,compact,bordered, andmodernthemes. - 📊 Excel & CSV Export — semantic
<table>compatible with SheetJS (xlsx) viagetTableElement(), plus built-in one-click CSV export viaexportToCSV(). - ↕️ Sticky Headers & Scrolling — configurable table viewport height and width.
📦 Installation
npm i ngx-modern-pivot-table📖 Usage Examples
1. Angular Usage (Standalone or NgModule)
Import PivotTableComponent (standalone) or NgxPivotTableModule in your module or standalone component:
import { Component, ViewChild } from '@angular/core';
import { PivotTableComponent, KeyOrder, PivotConfig } from 'ngx-modern-pivot-table';
@Component({
selector: 'app-report',
standalone: true,
imports: [PivotTableComponent],
template: `
<ngx-pivot-table
#pivotRef
[data]="salesData"
[rows]="['Region', 'Category']"
[cols]="['Year']"
[vals]="['Sales']"
[aggregatorName]="'Sum'"
[theme]="'modern'"
[height]="'600px'"
[stickyHeader]="true"
[(rowOrder)]="rowOrder"
[(colOrder)]="colOrder"
(configChange)="onConfigChange($event)"
(ready)="onPivotReady($event)"
(cellClick)="onCellClick($event)">
</ngx-pivot-table>
`
})
export class ReportComponent {
@ViewChild('pivotRef') pivotRef!: PivotTableComponent;
rowOrder: KeyOrder = 'key_a_to_z';
colOrder: KeyOrder = 'key_a_to_z';
salesData = [
{ Region: 'North', Category: 'Electronics', Year: '2024', Sales: 100 },
{ Region: 'North', Category: 'Furniture', Year: '2024', Sales: 200 },
{ Region: 'South', Category: 'Electronics', Year: '2024', Sales: 150 },
{ Region: 'South', Category: 'Furniture', Year: '2025', Sales: 350 }
];
onConfigChange(newConfig: PivotConfig) {
console.log('Configuration changed:', newConfig);
}
onPivotReady(result: any) {
console.log('Pivot matrix computed:', result);
}
onCellClick(cell: any) {
console.log('Clicked cell:', cell);
}
exportCSV() {
this.pivotRef.exportToCSV('sales-report.csv');
}
}Include styles in styles.scss or angular.json:
@import "ngx-modern-pivot-table/styles.scss";2. Vanilla TypeScript / JavaScript Usage
import { PivotUI } from 'ngx-modern-pivot-table';
const container = document.getElementById('pivot-container')!;
const pivot = new PivotUI(container, {
data: myData,
rows: ['Department'],
cols: ['Month'],
vals: ['Budget'],
aggregatorName: 'Sum',
theme: 'modern',
showUI: true,
onConfigChange: (newConfig) => {
console.log('Configuration updated:', newConfig);
}
});3. Pure Headless Node.js / Core Engine
import { PivotEngine } from 'ngx-modern-pivot-table';
const engine = new PivotEngine({
data: myData,
rows: ['Region'],
cols: ['Year'],
vals: ['Amount'],
aggregatorName: 'Average'
});
const result = engine.compute();
console.log('Grand Total:', result.grandTotal?.value());
console.log('Row Keys:', result.rowKeys);
console.log('Col Keys:', result.colKeys);⚙️ Configuration Options
| Property | Type | Default | Description |
|---|---|---|---|
| data | Record<string, any>[] | [] | Array of raw input data objects |
| rows | string[] | [] | Array of field keys to group by on the vertical axis |
| cols | string[] | [] | Array of field keys to group by on the horizontal axis |
| vals | string[] | [] | Target measurement field keys for aggregation |
| aggregatorName | string | 'Sum' | Aggregator function name (Sum, Count, Average, Min, Max, Median, Count Unique Values, etc.) |
| theme | 'default' | 'compact' | 'bordered' | 'modern' | 'dark' | 'default' | Visual theme style |
| width | string | '100%' | Width of the container (e.g. '100%', '1200px') |
| height | string | 'auto' | Max-height for scrollable table viewport (e.g. '600px', 'calc(100vh - 250px)') |
| showUI | boolean | true | Show/hide the interactive drag-and-drop & control bar |
| stickyHeader | boolean | true | Enable sticky column headers while scrolling vertically |
| showRowTotals | boolean | true | Display horizontal row total summaries |
| showColTotals | boolean | true | Display vertical column total summaries |
| showGrandTotal | boolean | true | Display the bottom-right grand total summary |
| rowOrder | 'key_a_to_z' | 'key_z_to_a' | 'value_a_to_z' | 'value_z_to_a' | 'key_a_to_z' | Sorting order for row dimension headers (supports two-way binding [(rowOrder)]) |
| colOrder | 'key_a_to_z' | 'key_z_to_a' | 'value_a_to_z' | 'value_z_to_a' | 'key_a_to_z' | Sorting order for column dimension headers (supports two-way binding [(colOrder)]) |
| inclusions | Record<string, string[]> | {} | Key-value mapping of allowed field values |
| exclusions | Record<string, string[]> | {} | Key-value mapping of excluded field values |
🛠️ Extending Aggregators
You can register custom aggregators:
import { registerAggregator, defaultNumberFormatter } from 'ngx-modern-pivot-table';
registerAggregator('Geometric Mean', (vals) => {
const field = vals[0];
let logSum = 0;
let count = 0;
return {
push: (record) => {
const v = Number(record[field]);
if (!isNaN(v) && v > 0) {
logSum += Math.log(v);
count++;
}
},
value: () => count === 0 ? null : Math.exp(logSum / count),
format: defaultNumberFormatter
};
});🧪 Testing & Verification
Run tests:
npm test📜 License
MIT © Arun VK
