@mindfiredigital/pivothead

PivotHead is a powerful and flexible library for creating interactive pivot tables in JavaScript applications. It provides a core engine for data manipulation and, in the future, will be compatible with wrappers for React, Vue, Svelte, and Angular, making
5,036 30
Install
npm install @mindfiredigital/pivothead
Latest Version:1.22.1
License:MIT
Last Updated:Apr 23, 2026
Links: GitHub  ·  npm
Maintainer: mindfire

PivotHead Core

Powerful TypeScript Pivot Table Engine for JavaScript Applications

npm version License: MIT TypeScript PRs Welcome

Features • Installation • Quick Start • API Reference • Examples • Support


Screenshots

PivotHead - Interactive Pivot Table

Features

** Core Capabilities**

  • Flexible data pivoting & aggregation
  • Multi-level grouping
  • Dynamic measures & dimensions
  • Custom formulas support
  • Sorting (asc/desc)
  • Advanced filtering

** Formatting & UI**

  • Conditional formatting
  • Currency & number formatting
  • Custom cell styling
  • Column resizing
  • Drag & drop for rows/columns
  • Responsive design
  • Toolbar customization

** Data Management**

  • Pagination support
  • Large dataset handling
  • Export to PDF/Excel/HTML
  • Local JSON/CSV file import
  • TypeScript support
  • Framework agnostic

Supported Aggregations

  • Sum - Total of all values
  • Average - Mean value
  • Count - Number of records
  • Min - Minimum value
  • Max - Maximum value
  • Custom formulas - Define your own calculations

Installation

# npm
npm install @mindfiredigital/pivothead

# yarn
yarn add @mindfiredigital/pivothead

# pnpm
pnpm add @mindfiredigital/pivothead

That's it! All dependencies including WebAssembly modules are automatically bundled. No additional configuration or manual file copying required.

Requirements

  • TypeScript (optional): 4.5.0 or higher
  • Node.js: 12.0.0 or higher

Quick Start

Basic Usage

import { PivotEngine } from '@mindfiredigital/pivothead';

// Your sales data
const data = [
  {
    date: '2024-01-01',
    product: 'Widget A',
    region: 'North',
    sales: 1000,
    quantity: 50,
  },
  {
    date: '2024-01-01',
    product: 'Widget B',
    region: 'South',
    sales: 1500,
    quantity: 75,
  },
  // ... more data
];

// Configure your pivot table
const config = {
  data: data,
  rows: [{ uniqueName: 'product', caption: 'Product' }],
  columns: [{ uniqueName: 'region', caption: 'Region' }],
  measures: [
    {
      uniqueName: 'sales',
      caption: 'Total Sales',
      aggregation: 'sum',
      format: {
        type: 'currency',
        currency: 'USD',
        locale: 'en-US',
        decimals: 2,
      },
    },
    {
      uniqueName: 'quantity',
      caption: 'Total Quantity',
      aggregation: 'sum',
      format: {
        type: 'number',
        decimals: 0,
        locale: 'en-US',
      },
    },
  ],
  dimensions: [
    { field: 'product', label: 'Product', type: 'string' },
    { field: 'region', label: 'Region', type: 'string' },
    { field: 'date', label: 'Date', type: 'date' },
    { field: 'sales', label: 'Sales', type: 'number' },
    { field: 'quantity', label: 'Quantity', type: 'number' },
  ],
  defaultAggregation: 'sum',
  isResponsive: true,
  pageSize: 10, // Enable pagination
};

// Create the pivot engine
const engine = new PivotEngine(config);

// Get the current state to render your UI
const state = engine.getState();
console.log('Pivot Data:', state);

With TypeScript

import {
  PivotEngine,
  PivotTableConfig,
  MeasureConfig,
} from '@mindfiredigital/pivothead';

interface SalesRecord {
  date: string;
  product: string;
  region: string;
  sales: number;
  quantity: number;
}

const config: PivotTableConfig<SalesRecord> = {
  data: salesData,
  rows: [{ uniqueName: 'product', caption: 'Product' }],
  columns: [{ uniqueName: 'region', caption: 'Region' }],
  measures: [
    {
      uniqueName: 'sales',
      caption: 'Total Sales',
      aggregation: 'sum',
      format: {
        type: 'currency',
        currency: 'USD',
        locale: 'en-US',
        decimals: 2,
      },
    },
  ],
  dimensions: [
    { field: 'product', label: 'Product', type: 'string' },
    { field: 'region', label: 'Region', type: 'string' },
    { field: 'sales', label: 'Sales', type: 'number' },
  ],
};

const engine = new PivotEngine<SalesRecord>(config);

API Reference

PivotEngine Class

The PivotEngine class is the core of the PivotHead library.

Constructor
constructor(config: PivotTableConfig<T>)

Creates a new instance of PivotEngine with the given configuration.


State Management

getState(): PivotTableState<T>

Returns the current state of the pivot table.

const state = engine.getState();
console.log(state.data); // Current data array
console.log(state.sortConfig); // Current sort configuration
console.log(state.filters); // Active filters
reset(): void

Resets the pivot table to its initial state.

engine.reset();
const state = engine.getState();
console.log(state); // Initial state restored

Data Manipulation

setMeasures(measureFields: MeasureConfig[]): void

Sets the measures for the pivot table.

engine.setMeasures([
  {
    uniqueName: 'revenue',
    caption: 'Total Revenue',
    aggregation: 'sum',
    format: { type: 'currency', currency: 'USD' },
  },
]);
setDimensions(dimensionFields: Dimension[]): void

Sets the dimensions for the pivot table.

engine.setDimensions([
  { field: 'category', label: 'Category', type: 'string' },
  { field: 'date', label: 'Date', type: 'date' },
]);
setAggregation(type: AggregationType): void

Sets the default aggregation type.

type AggregationType = 'sum' | 'avg' | 'count' | 'min' | 'max';

engine.setAggregation('avg');

Formatting

formatValue(value: any, field: string): string

Formats a value based on the specified field's format configuration.

const formattedValue = engine.formatValue(1000, 'sales');
console.log(formattedValue); // "$1,000.00"

Sorting and Grouping

sort(field: string, direction: 'asc' | 'desc'): void

Sorts the pivot table data.

engine.sort('sales', 'desc'); // Sort by sales descending
setGroupConfig(groupConfig: GroupConfig | null): void

Sets the group configuration for the pivot table.

engine.setGroupConfig({
  rowFields: ['product', 'category'],
  columnFields: ['region'],
  grouper: (item, fields) => fields.map(field => item[field]).join(' - '),
});
getGroupedData(): Group[]

Returns the grouped data.

const groupedData = engine.getGroupedData();
console.log(groupedData);

Row and Column Manipulation

resizeRow(index: number, height: number): void

Resizes a specific row in the pivot table.

engine.resizeRow(2, 60); // Set row 2 height to 60px
toggleRowExpansion(rowId: string): void

Toggles the expansion state of a row.

engine.toggleRowExpansion('product-123');
isRowExpanded(rowId: string): boolean

Checks if a specific row is expanded.

if (engine.isRowExpanded('product-123')) {
  console.log('Row is expanded');
}
dragRow(fromIndex: number, toIndex: number): void

Handles dragging a row to a new position.

engine.dragRow(0, 5); // Move row from index 0 to 5
dragColumn(fromIndex: number, toIndex: number): void

Handles dragging a column to a new position.

engine.dragColumn(1, 3); // Move column from index 1 to 3

Filtering and Pagination

applyFilters(filters: FilterConfig[]): void

Applies filters to the data.

engine.applyFilters([
  { field: 'region', operator: 'equals', value: 'North' },
  { field: 'sales', operator: 'greaterThan', value: 500 },
]);

Filter Operators:

  • equals - Exact match
  • contains - String contains (case-insensitive)
  • greaterThan - Numeric greater than
  • lessThan - Numeric less than
  • between - Value within range (requires array: [min, max])
setPagination(config: PaginationConfig): void

Sets the pagination configuration.

engine.setPagination({
  currentPage: 2,
  pageSize: 25,
});
getFilterState(): FilterConfig[]

Returns the current filter configuration.

const currentFilters = engine.getFilterState();
console.log(currentFilters);
getPaginationState(): PaginationConfig

Returns the current pagination configuration.

const paginationInfo = engine.getPaginationState();
console.log(
  `Page ${paginationInfo.currentPage} of ${paginationInfo.totalPages}`
);

Advanced Features

Conditional Formatting

Apply custom styles to cells based on their values.

const config = {
  // ... other configuration
  conditionalFormatting: [
    {
      value: {
        type: 'Number',
        operator: 'Greater than',
        value1: '1000',
        value2: '',
      },
      format: {
        font: 'Arial',
        size: '14px',
        color: '#ffffff',
        backgroundColor: '#4CAF50', // Green background for high values
      },
    },
    {
      value: {
        type: 'Number',
        operator: 'Less than',
        value1: '500',
        value2: '',
      },
      format: {
        font: 'Arial',
        size: '14px',
        color: '#ffffff',
        backgroundColor: '#f44336', // Red background for low values
      },
    },
  ],
};

Custom Measures with Formulas

Define custom calculated measures:

const config = {
  // ... other configuration
  measures: [
    {
      uniqueName: 'sales',
      caption: 'Total Sales',
      aggregation: 'sum',
    },
    {
      uniqueName: 'quantity',
      caption: 'Total Quantity',
      aggregation: 'sum',
    },
    {
      uniqueName: 'averageSale',
      caption: 'Average Sale Price',
      aggregation: 'avg',
      format: {
        type: 'currency',
        currency: 'USD',
        locale: 'en-US',
        decimals: 2,
      },
      formula: item => item.sales / item.quantity, // Custom calculation
    },
  ],
};

Cell Formatting

Format numbers and currencies:

const config = {
  // ... other configuration
  measures: [
    {
      uniqueName: 'sales',
      caption: 'Total Sales',
      aggregation: 'sum',
      format: {
        type: 'currency',
        currency: 'EUR', // Euro symbol
        locale: 'de-DE', // German locale
        decimals: 2,
      },
    },
    {
      uniqueName: 'percentage',
      caption: 'Growth Rate',
      aggregation: 'avg',
      format: {
        type: 'number',
        decimals: 2,
        locale: 'en-US',
      },
    },
  ],
};

Initial Sorting

Configure initial sort order:

const config = {
  // ... other configuration
  initialSort: [
    {
      field: 'sales',
      direction: 'desc',
      type: 'measure',
      aggregation: 'sum',
    },
  ],
};

Toolbar Visibility

Show or hide the toolbar:

const config = {
  // ... other configuration
  toolbar: true, // or false to hide
};

Configuration Interface

interface PivotTableConfig<T> {
  data: T[];
  rows: { uniqueName: string; caption: string }[];
  columns: { uniqueName: string; caption: string }[];
  measures: MeasureConfig[];
  dimensions: Dimension[];
  defaultAggregation?: AggregationType;
  isResponsive?: boolean;
  pageSize?: number;
  toolbar?: boolean;
  groupConfig?: GroupConfig;
  formatting?: Record<string, FormatConfig>;
  conditionalFormatting?: ConditionalFormattingRule[];
  initialSort?: SortConfig[];
  dataSource?: {
    type: 'remote' | 'file';
    url?: string;
    file?: File;
  };
  onRowDragEnd?: (fromIndex: number, toIndex: number, data: T[]) => void;
  onColumnDragEnd?: (
    fromIndex: number,
    toIndex: number,
    columns: Array<{ uniqueName: string; caption: string }>
  ) => void;
}

Examples

Example 1: Sales Dashboard with Filtering

import { PivotEngine } from '@mindfiredigital/pivothead';

const engine = new PivotEngine(config);

// Apply filters to show only high-value sales in the North region
engine.applyFilters([
  { field: 'region', operator: 'equals', value: 'North' },
  { field: 'sales', operator: 'greaterThan', value: 1000 },
]);

// Set up pagination
engine.setPagination({
  currentPage: 1,
  pageSize: 10,
});

// Get the filtered, paginated data
const state = engine.getState();
renderPivotTable(state);

Example 2: Range Filtering

// Filter sales between $500 and $1500
engine.applyFilters([
  {
    field: 'sales',
    operator: 'between',
    value: [500, 1500],
  },
]);

Example 3: Custom Grouping

const config = {
  // ... other configuration
  groupConfig: {
    rowFields: ['category', 'product'],
    columnFields: ['region', 'quarter'],
    grouper: (item, fields) => {
      return fields.map(field => item[field]).join(' > ');
    },
  },
};

const engine = new PivotEngine(config);
const groupedData = engine.getGroupedData();

Live Examples

Check out complete working examples:

Running Examples Locally

# Clone the repository
git clone https://github.com/mindfiredigital/PivotHead.git
cd PivotHead

# Navigate to an example (e.g., vanilla-pivot-demo)
cd examples/vanilla-pivot-demo

# Install dependencies
pnpm install

# Build the project
pnpm build

# Start the development server
pnpm start

# Open your browser to the local host address provided

Build pivot tables for any framework:

Package Description Documentation
@mindfiredigital/pivothead-react React wrapper component README
@mindfiredigital/pivothead-web-component Framework-agnostic web component README
@mindfiredigital/pivothead-vue Vue wrapper Coming soon

Show Your Support

If PivotHead helps your project, please consider:


License

Copyright © Mindfiredigital. All rights reserved.

Licensed under the MIT license.


Built with ❤️ by the Mindfiredigital team

NPM • GitHub • Website

Related Packages

Version History

Version Released License
1.22.1 MIT
1.22.0 MIT
1.21.0 MIT
1.20.0 MIT
1.17.0 MIT