Skip to content

RFC: PivotHead Analytics - Chart Generation Package #266

@lakinmindfire

Description

@lakinmindfire

What problem does this feature solve?

RFC: PivotHead Analytics - Chart Generation Package

Document Version: 1.0
Date: January 30, 2026
Status: Proposal
Package Name: @mindfiredigital/pivothead-analytics
Dependencies: @mindfiredigital/pivothead (core engine)


Executive Summary

PivotHead Analytics is a companion package to PivotHead that automatically generates interactive charts and visualizations from pivot data. It provides:

  1. Zero-config chart generation - Automatically detect best chart type from pivot structure
  2. Multiple chart libraries - Support for Chart.js, D3.js, Plotly, ECharts
  3. Smart recommendations - Suggest optimal visualizations based on data characteristics
  4. Seamless integration - Works directly with PivotEngine output
  5. Interactive features - Drill-down, filtering, export capabilities
  6. Performance optimized - Handles large datasets using WebAssembly aggregation

1. Architecture Overview

1.1 Package Structure

@mindfiredigital/pivothead-analytics/
├── src/
│   ├── core/
│   │   ├── ChartEngine.ts           # Main chart generation engine
│   │   ├── ChartDetector.ts         # Auto-detect best chart type
│   │   ├── DataTransformer.ts       # Pivot → Chart data adapter
│   │   └── ChartRecommender.ts      # Smart chart suggestions
│   ├── renderers/
│   │   ├── ChartJsRenderer.ts       # Chart.js adapter
│   │   ├── D3Renderer.ts            # D3.js adapter
│   │   ├── PlotlyRenderer.ts        # Plotly adapter
│   │   └── EChartsRenderer.ts       # Apache ECharts adapter
│   ├── charts/
│   │   ├── BarChart.ts
│   │   ├── LineChart.ts
│   │   ├── PieChart.ts
│   │   ├── ScatterChart.ts
│   │   ├── HeatmapChart.ts
│   │   ├── TreemapChart.ts
│   │   └── ComboChart.ts
│   ├── utils/
│   │   ├── ColorPalettes.ts         # Pre-defined color schemes
│   │   ├── Formatters.ts            # Number/date formatting
│   │   └── Exporters.ts             # Export to PNG/SVG/PDF
│   └── index.ts
├── examples/
│   ├── basic-usage.ts
│   ├── auto-detection.ts
│   └── custom-styling.ts
├── package.json
└── README.md

1.2 Data Flow

┌─────────────────────┐
│   Raw Data Array    │
│   (User's data)     │
└──────────┬──────────┘
           │
           ▼
┌─────────────────────┐
│   PivotEngine       │
│   (Aggregation)     │
└──────────┬──────────┘
           │
           ▼
┌─────────────────────┐
│  Pivot Output       │
│  {headers, cells}   │
└──────────┬──────────┘
           │
           ▼
┌─────────────────────┐
│  ChartEngine        │
│  (Analytics)        │
├─────────────────────┤
│ 1. Detect structure │
│ 2. Recommend charts │
│ 3. Transform data   │
│ 4. Render chart     │
└──────────┬──────────┘
           │
           ▼
┌─────────────────────┐
│  Interactive Chart  │
│  (Chart.js/D3/etc)  │
└─────────────────────┘

2. Core API Design

2.1 Basic Usage

import { PivotEngine } from '@mindfiredigital/pivothead';
import { ChartEngine } from '@mindfiredigital/pivothead-analytics';

// Step 1: Create pivot engine with data
const pivot = new PivotEngine({
  data: salesData,
  rows: [{ uniqueName: 'product' }],
  columns: [{ uniqueName: 'region' }],
  measures: [{ uniqueName: 'sales', aggregation: 'sum' }]
});

// Step 2: Create chart engine
const chartEngine = new ChartEngine(pivot);

// Step 3: Generate chart (auto-detect best type)
const chart = chartEngine.auto({
  container: '#chart-container',
  library: 'chartjs' // or 'd3', 'plotly', 'echarts'
});

// Alternative: Explicit chart type
const barChart = chartEngine.bar({
  container: '#chart-container',
  title: 'Sales by Product and Region',
  orientation: 'vertical'
});

2.2 Advanced Configuration

// Chart with full customization
const chart = chartEngine.bar({
  container: '#chart-container',
  
  // Data configuration
  data: {
    measure: 'sales',           // Which measure to visualize
    groupBy: 'product',         // Primary grouping
    stackBy: 'region',          // Secondary grouping (stacked bars)
    filters: [
      { field: 'date', op: '>=', value: '2024-01-01' }
    ]
  },
  
  // Visual styling
  style: {
    title: 'Sales Analysis',
    subtitle: 'Q1 2024',
    colorScheme: 'tableau10',   // Pre-defined palette
    orientation: 'horizontal',
    showLegend: true,
    showGrid: true,
    showValues: true            // Show values on bars
  },
  
  // Interactivity
  interactions: {
    hover: true,
    click: (data) => {
      console.log('Clicked:', data);
    },
    drillDown: {
      enabled: true,
      levels: ['product', 'region', 'date']
    }
  },
  
  // Formatting
  format: {
    valueFormat: 'currency',
    locale: 'en-US',
    decimals: 0
  },
  
  // Export options
  export: {
    enabled: true,
    formats: ['png', 'svg', 'pdf', 'csv']
  }
});

2.3 Smart Chart Recommendations

// Get chart recommendations based on data characteristics
const recommendations = chartEngine.recommend();

console.log(recommendations);
/*
[
  {
    type: 'bar',
    score: 0.95,
    reason: 'Best for comparing categories (5 products)',
    preview: 'https://...',
    config: { ... }
  },
  {
    type: 'heatmap',
    score: 0.85,
    reason: 'Good for showing patterns across 2 dimensions',
    preview: 'https://...',
    config: { ... }
  },
  {
    type: 'line',
    score: 0.70,
    reason: 'Suitable if time series added',
    preview: 'https://...',
    config: { ... }
  }
]
*/

// Render the top recommendation
const bestChart = chartEngine.render(recommendations[0].config);

3. Chart Type Implementations

3.1 Bar Chart

Use Cases:

  • Compare values across categories
  • Show rankings
  • Display distributions
const barChart = chartEngine.bar({
  container: '#chart',
  data: {
    measure: 'sales',
    groupBy: 'product',
    stackBy: 'region'  // Optional: stacked bars
  },
  style: {
    orientation: 'vertical',  // or 'horizontal'
    barWidth: 0.8,
    gap: 0.2
  }
});

// Generated data structure for Chart.js:
{
  labels: ['Widget A', 'Widget B', 'Widget C'],
  datasets: [
    {
      label: 'North',
      data: [1000, 1500, 1200],
      backgroundColor: '#4e79a7'
    },
    {
      label: 'South',
      data: [800, 1300, 1000],
      backgroundColor: '#f28e2c'
    }
  ]
}

3.2 Line Chart

Use Cases:

  • Show trends over time
  • Compare multiple series
  • Identify patterns
const lineChart = chartEngine.line({
  container: '#chart',
  data: {
    measure: 'sales',
    xAxis: 'date',
    seriesBy: 'product'
  },
  style: {
    lineType: 'smooth',  // or 'stepped', 'linear'
    showPoints: true,
    areaFill: false
  }
});

3.3 Pie Chart

Use Cases:

  • Show part-to-whole relationships
  • Display market share
  • Composition analysis
const pieChart = chartEngine.pie({
  container: '#chart',
  data: {
    measure: 'sales',
    groupBy: 'product'
  },
  style: {
    donut: false,        // true for donut chart
    innerRadius: 0,
    showPercentages: true,
    showLabels: true
  }
});

3.4 Heatmap

Use Cases:

  • Show intensity across 2 dimensions
  • Identify patterns in matrix data
  • Correlation analysis
const heatmap = chartEngine.heatmap({
  container: '#chart',
  data: {
    measure: 'sales',
    xAxis: 'region',
    yAxis: 'product'
  },
  style: {
    colorScale: 'sequential',  // or 'diverging'
    colorScheme: 'blues',
    showValues: true
  }
});

// Perfect for pivot table data with 2D structure

3.5 Scatter Plot

Use Cases:

  • Show correlation between 2 measures
  • Identify outliers
  • Clustering analysis
const scatter = chartEngine.scatter({
  container: '#chart',
  data: {
    xMeasure: 'sales',
    yMeasure: 'quantity',
    groupBy: 'product',
    sizeBy: 'profit'    // Bubble chart
  },
  style: {
    pointSize: 5,
    showTrendLine: true
  }
});

3.6 Treemap

Use Cases:

  • Hierarchical data visualization
  • Show proportions with nesting
  • Drill-down navigation
const treemap = chartEngine.treemap({
  container: '#chart',
  data: {
    measure: 'sales',
    hierarchy: ['region', 'product', 'salesperson']
  },
  style: {
    colorBy: 'value',
    showLabels: true,
    border: 1
  }
});

3.7 Combo Chart

Use Cases:

  • Compare different measure types
  • Show relationship between metrics
  • Dual-axis visualization
const combo = chartEngine.combo({
  container: '#chart',
  data: {
    xAxis: 'date',
    series: [
      { measure: 'sales', type: 'bar' },
      { measure: 'profit', type: 'line', yAxis: 'secondary' }
    ]
  }
});

4. Smart Chart Detection Algorithm

4.1 Detection Rules

class ChartDetector {
  /**
   * Analyze pivot structure and recommend best chart type
   */
  detect(pivotOutput: PivotOutput, config: PivotConfig): ChartRecommendation[] {
    const scores = [];
    
    // Rule 1: Single dimension → Pie chart
    if (config.rows.length === 1 && config.columns.length === 0) {
      scores.push({
        type: 'pie',
        score: 0.90,
        reason: 'Single categorical dimension - perfect for pie chart'
      });
    }
    
    // Rule 2: 1 row × 1 column → Bar or Heatmap
    if (config.rows.length === 1 && config.columns.length === 1) {
      const rowCount = pivotOutput.headers.rowHeaders.length;
      const colCount = pivotOutput.headers.columnHeaders.length;
      
      if (rowCount <= 10 && colCount <= 10) {
        scores.push({
          type: 'bar',
          score: 0.95,
          reason: `Small matrix (${rowCount}×${colCount}) - bar chart shows comparisons clearly`
        });
        
        scores.push({
          type: 'heatmap',
          score: 0.85,
          reason: 'Heatmap shows patterns across both dimensions'
        });
      } else {
        scores.push({
          type: 'heatmap',
          score: 0.90,
          reason: `Large matrix (${rowCount}×${colCount}) - heatmap handles scale better`
        });
      }
    }
    
    // Rule 3: Time series → Line chart
    if (this.hasTimeDimension(config.dimensions)) {
      scores.push({
        type: 'line',
        score: 0.92,
        reason: 'Time dimension detected - line chart shows trends'
      });
    }
    
    // Rule 4: Multiple measures → Combo chart
    if (config.measures.length > 1) {
      scores.push({
        type: 'combo',
        score: 0.80,
        reason: `${config.measures.length} measures - combo chart compares different metrics`
      });
    }
    
    // Rule 5: Hierarchical structure → Treemap
    if (config.rows.length >= 2) {
      scores.push({
        type: 'treemap',
        score: 0.75,
        reason: `${config.rows.length}-level hierarchy - treemap shows proportions`
      });
    }
    
    // Rule 6: 2 numeric measures → Scatter
    const numericMeasures = config.measures.filter(m => 
      config.dimensions.find(d => d.field === m.uniqueName)?.type === 'number'
    );
    
    if (numericMeasures.length >= 2) {
      scores.push({
        type: 'scatter',
        score: 0.70,
        reason: 'Multiple numeric measures - scatter plot shows correlation'
      });
    }
    
    // Sort by score and return top recommendations
    return scores.sort((a, b) => b.score - a.score);
  }
  
  private hasTimeDimension(dimensions: Dimension[]): boolean {
    return dimensions.some(d => 
      d.type === 'date' || 
      d.field.toLowerCase().includes('date') ||
      d.field.toLowerCase().includes('time')
    );
  }
}

4.2 Decision Matrix

Pivot Structure Row Count Col Count Measures Best Chart Alt Chart
1 row, 0 cols 5-10 - 1 Pie Bar
1 row, 1 col 5-10 5-10 1 Bar (grouped) Heatmap
1 row, 1 col >10 >10 1 Heatmap Treemap
1 row (time) Any - 1 Line Area
1 row (time) Any - >1 Combo Multi-line
2+ rows Any - 1 Treemap Stacked bar
2 measures - - 2 Scatter Bubble
Complex >20 >5 >1 Heatmap Pivot table

5. Data Transformation Layer

5.1 Pivot Output → Chart Data Adapter

class DataTransformer {
  /**
   * Transform pivot table output to chart data format
   */
  toChartData(
    pivotOutput: PivotOutput,
    chartType: ChartType,
    options: TransformOptions
  ): ChartData {
    switch (chartType) {
      case 'bar':
        return this.toBarData(pivotOutput, options);
      case 'line':
        return this.toLineData(pivotOutput, options);
      case 'pie':
        return this.toPieData(pivotOutput, options);
      case 'heatmap':
        return this.toHeatmapData(pivotOutput, options);
      default:
        throw new Error(`Unsupported chart type: ${chartType}`);
    }
  }
  
  /**
   * Transform for bar chart (Chart.js format)
   */
  private toBarData(pivotOutput: PivotOutput, options: TransformOptions): BarChartData {
    const { headers, cells } = pivotOutput;
    const { measure, groupBy, stackBy } = options;
    
    // Extract row headers as labels
    const labels = headers.rowHeaders.map(row => row[0]);
    
    // Extract column headers as series
    const columnLabels = headers.columnHeaders.map(col => col[0]);
    
    // Create datasets (one per column)
    const datasets = columnLabels.map((label, colIndex) => ({
      label: label,
      data: cells.map(row => row[colIndex]),
      backgroundColor: this.getColor(colIndex),
      borderColor: this.getBorderColor(colIndex),
      borderWidth: 1
    }));
    
    return {
      labels,
      datasets
    };
  }
  
  /**
   * Transform for heatmap (ECharts format)
   */
  private toHeatmapData(pivotOutput: PivotOutput, options: TransformOptions): HeatmapData {
    const { headers, cells } = pivotOutput;
    
    // Flatten to [x, y, value] format
    const data = [];
    
    cells.forEach((row, rowIndex) => {
      row.forEach((value, colIndex) => {
        data.push([
          colIndex,  // x: column index
          rowIndex,  // y: row index
          value      // value: cell value
        ]);
      });
    });
    
    return {
      xAxis: {
        data: headers.columnHeaders.map(col => col[0])
      },
      yAxis: {
        data: headers.rowHeaders.map(row => row[0])
      },
      series: [{
        type: 'heatmap',
        data: data,
        label: {
          show: true
        }
      }]
    };
  }
  
  /**
   * Transform for pie chart
   */
  private toPieData(pivotOutput: PivotOutput, options: TransformOptions): PieChartData {
    const { headers, cells } = pivotOutput;
    
    // Aggregate all columns (if multiple)
    const data = headers.rowHeaders.map((row, index) => ({
      name: row[0],
      value: cells[index].reduce((sum, val) => sum + val, 0)
    }));
    
    return {
      labels: data.map(d => d.name),
      datasets: [{
        data: data.map(d => d.value),
        backgroundColor: data.map((_, i) => this.getColor(i))
      }]
    };
  }
}

5.2 Example Transformation

Input (Pivot Output):

{
  "headers": {
    "rowHeaders": [["Widget A"], ["Widget B"], ["Widget C"]],
    "columnHeaders": [["North"], ["South"], ["East"]]
  },
  "cells": [
    [1000, 800, 1200],
    [1500, 1300, 1600],
    [1100, 900, 1400]
  ]
}

Output (Bar Chart Data - Chart.js):

{
  "labels": ["Widget A", "Widget B", "Widget C"],
  "datasets": [
    {
      "label": "North",
      "data": [1000, 1500, 1100],
      "backgroundColor": "#4e79a7"
    },
    {
      "label": "South",
      "data": [800, 1300, 900],
      "backgroundColor": "#f28e2c"
    },
    {
      "label": "East",
      "data": [1200, 1600, 1400],
      "backgroundColor": "#e15759"
    }
  ]
}

6. Renderer Implementations

6.1 Chart.js Renderer

class ChartJsRenderer implements ChartRenderer {
  render(config: ChartConfig): Chart {
    const chartData = this.transformer.toChartData(config);
    
    return new Chart(config.container, {
      type: config.type,
      data: chartData,
      options: {
        responsive: true,
        maintainAspectRatio: false,
        plugins: {
          title: {
            display: true,
            text: config.style.title
          },
          legend: {
            display: config.style.showLegend,
            position: 'bottom'
          },
          tooltip: {
            callbacks: {
              label: (context) => {
                const value = this.formatter.format(
                  context.parsed.y,
                  config.format
                );
                return `${context.dataset.label}: ${value}`;
              }
            }
          }
        },
        scales: {
          y: {
            beginAtZero: true,
            ticks: {
              callback: (value) => this.formatter.format(value, config.format)
            }
          }
        }
      }
    });
  }
}

6.2 ECharts Renderer

class EChartsRenderer implements ChartRenderer {
  render(config: ChartConfig): echarts.ECharts {
    const container = document.querySelector(config.container);
    const chart = echarts.init(container);
    
    const option = {
      title: {
        text: config.style.title,
        left: 'center'
      },
      tooltip: {
        trigger: 'axis',
        formatter: (params) => {
          return params.map(p => 
            `${p.seriesName}: ${this.formatter.format(p.value, config.format)}`
          ).join('<br/>');
        }
      },
      legend: {
        show: config.style.showLegend,
        bottom: 0
      },
      xAxis: {
        type: 'category',
        data: config.data.labels
      },
      yAxis: {
        type: 'value',
        axisLabel: {
          formatter: (value) => this.formatter.format(value, config.format)
        }
      },
      series: config.data.datasets.map(ds => ({
        name: ds.label,
        type: config.type,
        data: ds.data,
        emphasis: {
          focus: 'series'
        }
      }))
    };
    
    chart.setOption(option);
    return chart;
  }
}

7. Integration Examples

7.1 Complete Example: Sales Dashboard

import { PivotEngine } from '@mindfiredigital/pivothead';
import { ChartEngine } from '@mindfiredigital/pivothead-analytics';

// Sample sales data
const salesData = [
  { 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: 60 },
  { date: '2024-01-02', product: 'Widget A', region: 'East', sales: 1200, quantity: 55 },
  { date: '2024-01-02', product: 'Widget B', region: 'West', sales: 1800, quantity: 70 },
  // ... more data
];

// Create pivot engine
const pivot = new PivotEngine({
  data: salesData,
  rows: [{ uniqueName: 'product', caption: 'Product' }],
  columns: [{ uniqueName: 'region', caption: 'Region' }],
  measures: [
    { uniqueName: 'sales', caption: 'Total Sales', aggregation: 'sum' }
  ],
  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' }
  ]
});

// Create chart engine
const chartEngine = new ChartEngine(pivot, {
  library: 'chartjs'  // or 'echarts', 'plotly', 'd3'
});

// Chart 1: Bar chart - Sales by Product & Region
const barChart = chartEngine.bar({
  container: '#chart-1',
  style: {
    title: 'Sales by Product and Region',
    colorScheme: 'tableau10',
    orientation: 'vertical',
    showLegend: true,
    showValues: true
  },
  format: {
    valueFormat: 'currency',
    locale: 'en-US',
    decimals: 0
  }
});

// Chart 2: Heatmap - Intensity view
const heatmap = chartEngine.heatmap({
  container: '#chart-2',
  style: {
    title: 'Sales Heatmap',
    colorScheme: 'blues',
    showValues: true
  }
});

// Chart 3: Auto-detect and render best chart
const autoChart = chartEngine.auto({
  container: '#chart-3'
});

// Chart 4: Get recommendations
const recommendations = chartEngine.recommend();
console.log('Top recommendation:', recommendations[0]);
// Render the recommended chart
chartEngine.render({
  container: '#chart-4',
  ...recommendations[0].config
});

7.2 Time Series Analysis

// Time series configuration
const pivot = new PivotEngine({
  data: timeSeriesData,
  rows: [{ uniqueName: 'date', caption: 'Date' }],
  columns: [{ uniqueName: 'product', caption: 'Product' }],
  measures: [
    { uniqueName: 'sales', aggregation: 'sum' }
  ]
});

const chartEngine = new ChartEngine(pivot);

// Line chart for trends
const lineChart = chartEngine.line({
  container: '#trend-chart',
  style: {
    title: 'Sales Trend Over Time',
    lineType: 'smooth',
    showPoints: true,
    areaFill: true
  }
});

// Combo chart: Sales (bars) + Profit % (line)
const combo = chartEngine.combo({
  container: '#combo-chart',
  data: {
    xAxis: 'date',
    series: [
      { measure: 'sales', type: 'bar', label: 'Sales' },
      { measure: 'profitMargin', type: 'line', yAxis: 'secondary', label: 'Profit %' }
    ]
  }
});

7.3 Interactive Drill-Down

// Enable drill-down capability
const chart = chartEngine.bar({
  container: '#interactive-chart',
  interactions: {
    drillDown: {
      enabled: true,
      levels: ['region', 'product', 'salesperson'],
      onDrill: (level, value) => {
        console.log(`Drilling into ${level}: ${value}`);
        
        // Update pivot filter
        pivot.updateConfig({
          filters: [
            { field: level, op: '=', value: value }
          ]
        });
        
        // Re-render chart with filtered data
        chart.update();
      }
    },
    click: (data) => {
      // Custom click handler
      console.log('Clicked:', data);
    }
  }
});

8. Color Palettes

8.1 Pre-defined Schemes

const ColorPalettes = {
  tableau10: [
    '#4e79a7', '#f28e2c', '#e15759', '#76b7b2', '#59a14f',
    '#edc949', '#af7aa1', '#ff9da7', '#9c755f', '#bab0ab'
  ],
  
  colorBlind: [
    '#006BA4', '#FF800E', '#ABABAB', '#595959', '#5F9ED1',
    '#C85200', '#898989', '#A2C8EC', '#FFBC79', '#CFCFCF'
  ],
  
  categorical: [
    '#1f77b4', '#ff7f0e', '#2ca02c', '#d62728', '#9467bd',
    '#8c564b', '#e377c2', '#7f7f7f', '#bcbd22', '#17becf'
  ],
  
  sequential_blues: [
    '#f7fbff', '#deebf7', '#c6dbef', '#9ecae1', '#6baed6',
    '#4292c6', '#2171b5', '#08519c', '#08306b'
  ],
  
  diverging: [
    '#d73027', '#f46d43', '#fdae61', '#fee090', '#ffffbf',
    '#e0f3f8', '#abd9e9', '#74add1', '#4575b4'
  ]
};

8.2 Dynamic Color Assignment

class ColorManager {
  getColor(index: number, scheme: string = 'tableau10'): string {
    const palette = ColorPalettes[scheme];
    return palette[index % palette.length];
  }
  
  generateGradient(startColor: string, endColor: string, steps: number): string[] {
    // Generate color gradient
    const colors = [];
    for (let i = 0; i < steps; i++) {
      const ratio = i / (steps - 1);
      colors.push(this.interpolateColor(startColor, endColor, ratio));
    }
    return colors;
  }
}

9. Export Capabilities

9.1 Export API

// Export chart as image
chartEngine.export({
  format: 'png',      // 'png', 'svg', 'pdf', 'csv', 'json'
  filename: 'sales-chart',
  width: 1920,
  height: 1080,
  quality: 0.95
});

// Export data as CSV
chartEngine.exportData({
  format: 'csv',
  filename: 'sales-data.csv',
  includeHeaders: true
});

// Export pivot + chart configuration
chartEngine.exportConfig({
  format: 'json',
  filename: 'dashboard-config.json'
});

10. Performance Considerations

10.1 Large Dataset Handling

// Automatic data sampling for large datasets
const chartEngine = new ChartEngine(pivot, {
  performance: {
    maxDataPoints: 1000,        // Sample if > 1000 points
    samplingMethod: 'stratified', // 'random', 'stratified', 'systematic'
    progressiveRendering: true,  // Render incrementally
    virtualScrolling: true       // For large legends
  }
});

10.2 Lazy Loading

// Load renderers on-demand
const chartEngine = new ChartEngine(pivot, {
  lazyLoad: true,  // Only load Chart.js when needed
  library: 'chartjs'
});

11. TypeScript Definitions

// Core types
export interface ChartConfig {
  container: string | HTMLElement;
  type?: ChartType;
  data?: DataConfig;
  style?: StyleConfig;
  interactions?: InteractionConfig;
  format?: FormatConfig;
  export?: ExportConfig;
}

export type ChartType = 
  | 'bar' 
  | 'line' 
  | 'pie' 
  | 'scatter' 
  | 'heatmap' 
  | 'treemap' 
  | 'combo';

export interface ChartRecommendation {
  type: ChartType;
  score: number;
  reason: string;
  preview?: string;
  config: ChartConfig;
}

export interface ChartEngine {
  auto(config: Partial<ChartConfig>): Chart;
  bar(config: BarChartConfig): Chart;
  line(config: LineChartConfig): Chart;
  pie(config: PieChartConfig): Chart;
  heatmap(config: HeatmapConfig): Chart;
  scatter(config: ScatterConfig): Chart;
  treemap(config: TreemapConfig): Chart;
  combo(config: ComboConfig): Chart;
  
  recommend(): ChartRecommendation[];
  render(config: ChartConfig): Chart;
  export(options: ExportOptions): Promise<Blob>;
}

12. Installation & Setup

12.1 Installation

# Install core package
npm install @mindfiredigital/pivothead

# Install analytics package
npm install @mindfiredigital/pivothead-analytics

# Install chart library (choose one)
npm install chart.js
# or
npm install echarts
# or
npm install plotly.js
# or
npm install d3

12.2 Basic Setup

<!DOCTYPE html>
<html>
<head>
  <title>PivotHead Analytics</title>
  <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
</head>
<body>
  <div id="chart-container" style="width: 800px; height: 600px;"></div>
  
  <script type="module">
    import { PivotEngine } from '@mindfiredigital/pivothead';
    import { ChartEngine } from '@mindfiredigital/pivothead-analytics';
    
    // Your code here
  </script>
</body>
</html>

13. Roadmap

Phase 1 (MVP) - 4 weeks

  • Core ChartEngine implementation
  • Chart.js renderer
  • Bar, Line, Pie charts
  • Basic data transformer
  • Auto-detection algorithm

Phase 2 - 3 weeks

  • Heatmap, Scatter, Treemap
  • ECharts renderer
  • Smart recommendations
  • Export capabilities
  • Interactive features

Phase 3 - 3 weeks

  • D3.js renderer
  • Plotly renderer
  • Advanced interactions (drill-down)
  • Animation support
  • Performance optimization

End of RFC

Last Updated: January 30, 2026
Status: Proposal - Ready for Review

Metadata

Metadata

Assignees

Labels

RFCRequest for Comments a formal, structured document that proposes a significant changedocumentationImprovements or additions to documentation

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions