npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

energy-visualization-stacked-area-chart

v2.0.0

Published

A modern TypeScript library for energy data stacked area charts with D3

Readme

Energy Stacked Area Chart Library

A modern TypeScript library for creating interactive energy data visualizations. Purpose-built for energy consumption analysis with built-in support for multiple energy sources, time series data, and various representation modes.

Why Energy Data Visualization Matters

Energy consumption patterns are complex, involving multiple sources (solar, nuclear, wind, coal, etc.) changing over decades of time. This library makes it simple to create beautiful, interactive charts that help researchers, policymakers, and educators understand energy trends and make data-driven decisions.

Key Features

Energy-Focused Design

  • 9 Energy Sources: Solar, Nuclear, Hydro, Wind, Geothermal, Natural Gas, Coal, Biomass, Petroleum
  • Smart Color Coding: Industry-standard colors for each energy source
  • Multiple Views: Fuel-based vs Sector-based energy analysis
  • Data Representations: Fractional, Per Capita, and Total consumption modes

Modern Developer Experience

  • Simple Data API: Provide data directly, no HTTP dependencies
  • TypeScript First: Complete type safety with strict mode
  • Zero Dependencies: Embedded D3 v7 for standalone distribution
  • Responsive Design: Automatic resizing and mobile-friendly
  • Instant Switching: Change modes/representations without re-fetching data

Production Ready

  • High Performance: Handles 200+ years × 9+ energy sources smoothly
  • Comprehensive Testing: 90%+ code coverage with unit and integration tests
  • Professional Styling: Matches industry visualization standards
  • Robust Error Handling: Graceful fallbacks and clear error messages

Quick Start

Installation

npm install energy-visualization-stacked-area-chart

Basic Usage

<!DOCTYPE html>
<html>
<head>
    <title>Energy Visualization</title>
</head>
<body>
<div id="energy-chart"></div>

<!-- Include the library -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/stacked-area-chart.umd.js"></script>

<script>
    // Fetch your energy data
    fetch('./energy-data.json')
            .then(response => response.json())
            .then(energyData => {
                // Create chart with data
                new StackedAreaChart.default('energy-chart', {
                    mode: 'fuel',
                    representation: 'perCapita',
                    data: energyData
                });
                // Chart auto-renders when data is provided
            });
</script>
</body>
</html>

ES6 Module Usage

// Named import (recommended)
import {StackedAreaChart} from 'energy-visualization-stacked-area-chart';
import 'energy-visualization-stacked-area-chart/style.css';

// Fetch data (you control the data loading)
const energyData = await fetch('./energy-data.json').then(r => r.json());

// Option 1: Provide data in constructor
const chart = new StackedAreaChart('energy-chart', {
    mode: 'fuel',
    representation: 'perCapita',
    data: energyData
});
// Auto-renders when data provided

// Option 2: Provide data via fluent API
const chart2 = new StackedAreaChart('energy-chart-2', {
    mode: 'fuel',
    representation: 'perCapita'
});
chart2.data(energyData).render();

// Instant switching between modes (no re-fetch needed)
chart.switchDataSource('sector', 'total');

Modern Framework Integration

The library is designed to work seamlessly with modern JavaScript frameworks and build tools. All exports are tree-shakeable and fully typed.

Importing

// Named import (recommended for frameworks)
import {StackedAreaChart} from 'energy-visualization-stacked-area-chart';

// Default import
import StackedAreaChart from 'energy-visualization-stacked-area-chart';

// Type imports
import type {ChartConfig, MultiDatasetFormat} from 'energy-visualization-stacked-area-chart';

// CSS import
import 'energy-visualization-stacked-area-chart/style.css';

Nuxt 3

Create a composable for easy chart management:

// composables/useEnergyChart.ts
import {ref, onMounted, onUnmounted, type Ref} from 'vue';
import {StackedAreaChart, type PartialChartConfig} from 'energy-visualization-stacked-area-chart';
import 'energy-visualization-stacked-area-chart/style.css';

export function useEnergyChart(
    containerId: string,
    config?: PartialChartConfig
): Ref<StackedAreaChart | null> {
    const chart = ref<StackedAreaChart | null>(null);

    onMounted(() => {
        chart.value = new StackedAreaChart(containerId, config || {});
    });

    onUnmounted(() => {
        chart.value?.destroy();
    });

    return chart;
}

Use in a component:

<template>
  <div>
    <div id="energy-chart" style="width: 100%; height: 400px;"></div>
  </div>
</template>

<script setup lang="ts">
import { onMounted } from 'vue';
import { useEnergyChart } from '~/composables/useEnergyChart';

const chart = useEnergyChart('energy-chart', {
  mode: 'fuel',
  representation: 'perCapita'
});

onMounted(async () => {
  const data = await $fetch('/api/energy-data');
  chart.value?.data(data).render();
});
</script>

Next.js (App Router)

'use client';

import { useEffect, useRef, useState } from 'react';
import { StackedAreaChart } from 'energy-visualization-stacked-area-chart';
import type { MultiDatasetFormat } from 'energy-visualization-stacked-area-chart';
import 'energy-visualization-stacked-area-chart/style.css';

export function EnergyChart({ data }: { data: MultiDatasetFormat }) {
  const chartRef = useRef<StackedAreaChart | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  
  useEffect(() => {
    if (!containerRef.current) return;
    
    // Create chart instance
    chartRef.current = new StackedAreaChart('energy-chart', {
      mode: 'fuel',
      representation: 'perCapita',
      data: data
    });
    
    // Cleanup on unmount
    return () => {
      chartRef.current?.destroy();
    };
  }, [data]);
  
  return (
    <div 
      id="energy-chart" 
      ref={containerRef} 
      style={{ width: '100%', height: '400px' }}
    />
  );
}

Vue 3

<template>
  <div id="energy-chart" style="width: 100%; height: 400px;"></div>
</template>

<script setup lang="ts">
import { onMounted, onUnmounted, ref } from 'vue';
import { StackedAreaChart } from 'energy-visualization-stacked-area-chart';
import type { PartialChartConfig, MultiDatasetFormat } from 'energy-visualization-stacked-area-chart';
import 'energy-visualization-stacked-area-chart/style.css';

interface Props {
  data: MultiDatasetFormat;
  config?: PartialChartConfig;
}

const props = defineProps<Props>();
const chart = ref<StackedAreaChart | null>(null);

onMounted(() => {
  chart.value = new StackedAreaChart('energy-chart', {
    ...props.config,
    data: props.data
  });
});

onUnmounted(() => {
  chart.value?.destroy();
});
</script>

React (Create React App / Vite)

import { useEffect, useRef } from 'react';
import { StackedAreaChart } from 'energy-visualization-stacked-area-chart';
import type { MultiDatasetFormat, PartialChartConfig } from 'energy-visualization-stacked-area-chart';
import 'energy-visualization-stacked-area-chart/style.css';

interface EnergyChartProps {
  data: MultiDatasetFormat;
  config?: PartialChartConfig;
}

export function EnergyChartComponent({ data, config }: EnergyChartProps) {
  const chartRef = useRef<StackedAreaChart | null>(null);
  const containerRef = useRef<HTMLDivElement>(null);
  
  useEffect(() => {
    if (!containerRef.current) return;
    
    chartRef.current = new StackedAreaChart('energy-chart-container', {
      ...config,
      data: data
    });
    
    return () => {
      chartRef.current?.destroy();
    };
  }, [data, config]);
  
  return (
    <div 
      id="energy-chart-container" 
      ref={containerRef}
      style={{ width: '100%', height: '400px' }}
    />
  );
}

TypeScript Support

All types are fully exported and documented:

import type {
    // Main class
    StackedAreaChart,

    // Configuration types
    ChartConfig,
    PartialChartConfig,
    ChartDimensions,
    TooltipConfig,
    AnimationConfig,

    // Data types
    MultiDatasetFormat,
    RawChartData,
    EnergySource,
    ProcessedDataPoint,

    // Enums and constants
    ChartMode,           // 'fuel' | 'sector'
    DataRepresentation,  // 'fractional' | 'perCapita' | 'total'
    EnergySourceName,

    // Utility types
    ChartBounds,
    DatasetKey
} from 'energy-visualization-stacked-area-chart';

// Default configuration is also exported
import {DEFAULT_CONFIG} from 'energy-visualization-stacked-area-chart';

Energy Data Features

Energy Sources & Colors

The library includes built-in support for standard energy sources with industry-recognized colors:

const energySources = {
    'Solar': '#fed530',        // Bright yellow
    'Nuclear': '#ca0813',      // Red  
    'Water': '#0b24fb',        // Blue (Hydro)
    'Wind': '#901d8f',         // Purple
    'Geothermal': '#905a1c',   // Brown
    'Natural Gas': '#4cabf2',  // Light blue
    'Coal': '#000000',         // Black
    'Biomass': '#46be48',      // Green
    'Petroleum': '#095f0b'     // Dark green
};

Data Representations

Fractional View: Shows energy sources as proportions (0-1) of total consumption

chart.representation('fractional'); // Perfect for seeing energy mix changes

Per Capita View: Shows energy consumption per person

chart.representation('perCapita');  // Great for population-adjusted analysis

Total View: Shows absolute energy consumption values

chart.representation('total');      // Best for seeing overall consumption growth

Energy Unit Formatting

Automatic formatting with appropriate energy units:

formatEnergyValue(1500);       // "1.5 kW"
formatEnergyValue(2500000);    // "2.5 MW" 
formatEnergyValue(1200000000); // "1.2 GW"

Data Format

The library uses a Multi-Dataset Format that contains all 6 data variants in a single object:

{
  "fuel-fractional": [...],
  "fuel-perCapita": [...],
  "fuel-total": [...],
  "sectoral-fractional": [...],
  "sectoral-perCapita": [...],
  "sectoral-total": [...]
}

Each array follows the energy source structure:

{
  "fuel-fractional": [
    {
      "year": [1800, 1801, 1802, ..., 2021]
    },
    {
      "name": "Solar",
      "color": "#fed530",
      "data": [0, 0, 0, ..., 131.23],
      "opacity": 1
    },
    {
      "name": "Nuclear",
      "color": "#ca0813",
      "data": [0, 0, 0, ..., 843.45],
      "opacity": 1
    }
    // ... more energy sources
  ],
  "fuel-perCapita": [
    // Same structure with per-capita values
  ],
  // ... other datasets
}

Key Points:

  • First object in each array contains the years
  • Subsequent objects represent energy sources with their data
  • All 6 datasets loaded once, enabling instant mode/representation switching

API Reference

Constructor

new StackedAreaChart(containerId: string, config ?: PartialChartConfig)

Parameters:

  • containerId: CSS selector or element ID for the chart container
  • config: Optional configuration object

Configuration Options

interface ChartConfig {
    // Chart dimensions
    dimensions: {
        width: number;          // Chart width (auto-calculated if not set)
        height: number;         // Chart height (auto-calculated if not set) 
        margin: {               // Chart margins
            top: number; right: number; bottom: number; left: number;
        };
    };

    // Energy data settings
    mode: 'fuel' | 'sector';                           // Analysis mode
    representation: 'fractional' | 'perCapita' | 'total'; // Data representation
    data?: MultiDatasetFormat;                         // Multi-dataset object (optional)

    // Styling and interaction
    interactive: boolean;       // Enable hover and tooltip interactions
    colors: Record<string, string>; // Custom energy source colors

    // Tooltip configuration  
    tooltip: {
        background: string;     // Tooltip background color
        color: string;          // Tooltip text color
        borderColor: string;    // Tooltip border color
        format: string;         // Number format pattern
    };

    // Animation settings
    animations: {
        duration: number;       // Animation duration in ms
        easing: string;         // CSS easing function
        enabled: boolean;       // Enable/disable animations
    };
}

Methods

Fluent API Methods (Chainable)

// Dimension control
chart.width(800)                       // Set chart width
chart.height(400)                      // Set chart height  
chart.resize(1000, 500)                // Resize chart

// Data control  
chart.mode('fuel')                     // Set to fuel-based analysis
chart.mode('sector')                   // Set to sector-based analysis  
chart.representation('perCapita')      // Set data representation
chart.data(multiDatasetObject)         // Provide multi-dataset
chart.updateData(multiDatasetObject)   // Update with new multi-dataset

// Data source switching (instant - no HTTP)
chart.switchDataSource('fuel', 'perCapita')  // Switch mode and representation

// Configuration
chart.configure({                      // Update configuration
    interactive: true,
    animations: {duration: 500}
});

Rendering Methods

chart.render()          // Render the chart
chart.update()          // Update with current data
chart.destroy()         // Clean up and remove chart

Utility Methods

chart.getConfig()       // Get current configuration
chart.getData()         // Get processed data points
chart.getEnergySources() // Get current energy sources
chart.getSVG()          // Get SVG element
chart.hasData()         // Check if chart has data

Advanced Usage

Custom Styling

const chart = new StackedAreaChart('chart', {
    dimensions: {
        width: 1200,
        height: 500,
        margin: {top: 20, right: 30, bottom: 40, left: 50}
    },
    colors: {
        'Solar': '#ffeb3b',      // Custom solar color
        'Wind': '#9c27b0'        // Custom wind color
    },
    tooltip: {
        background: '#ffffff',
        borderColor: '#333333',
        color: '#333333'
    }
});

Programmatic Control

// Fetch data once
const energyData = await fetch('./energy-data.json').then(r => r.json());

const chart = new StackedAreaChart('chart', {
    data: energyData,
    mode: 'fuel',
    representation: 'perCapita'
});

// Instant switching (no re-fetch needed)
document.getElementById('fuel-btn').addEventListener('click', () => {
    chart.switchDataSource('fuel', 'perCapita');
});

document.getElementById('sector-btn').addEventListener('click', () => {
    chart.switchDataSource('sector', 'total');
});

// Responsive behavior
window.addEventListener('resize', () => {
    const container = document.getElementById('chart-container');
    chart.resize(container.clientWidth, 400);
});

Custom Data Loading

// Load and provide your own energy data
async function loadCustomData() {
    const response = await fetch('/api/energy-data');
    const multiDataset = await response.json();

    // Ensure data matches MultiDatasetFormat structure
    const chart = new StackedAreaChart('chart', {
        mode: 'fuel',
        representation: 'perCapita'
    });

    chart.data(multiDataset).render();
}

Performance

Optimized for Large Datasets

  • Time Range: Efficiently handles 200+ years of historical data
  • Energy Sources: Supports 9+ concurrent energy sources
  • Data Points: Processes thousands of data points smoothly
  • Rendering: <100ms render time for typical energy datasets
  • Memory: Efficient D3 data joins minimize memory usage

Bundle Size

  • UMD Bundle: 67KB (includes embedded D3)
  • ESM Bundle: 67KB (tree-shakeable)
  • Compressed: ~18KB gzipped
  • Dependencies: Zero runtime dependencies

Development

Setup Development Environment

# Clone and install
git clone <repository-url>
cd stacked-area-1
npm install

# Development with hot reload
npm run dev

# Run tests
npm test
npm run test:watch
npm run test:coverage

# Build for production  
npm run build

Project Structure

src/
├── core/           # Main chart engine
│   ├── StackedAreaChart.ts    # Primary chart class
│   ├── DataProcessor.ts       # Data transformation
│   └── Renderer.ts            # D3 rendering engine
├── components/     # UI components
│   └── Tooltip.ts             # Interactive tooltips
├── utils/          # Utility functions
│   ├── formatters.ts          # Energy value formatting
│   ├── colorMaps.ts           # Energy source colors
│   └── constants.ts           # Configuration constants
├── types/          # TypeScript definitions
└── styles/         # CSS styling

Testing Strategy

# Unit tests - Core functionality
npm run test:unit

# Integration tests - Full workflows
npm run test:integration  

# Performance tests - Large datasets
npm run test:performance

# All tests with coverage
npm run test:coverage

Browser Support

  • Modern Browsers: Chrome 63+, Firefox 60+, Safari 12+, Edge 79+
  • JavaScript: ES2018+ support required
  • Features Used: ResizeObserver, Fetch API, ES6 Modules
  • Fallbacks: Graceful degradation for older browsers

Build Tools & Bundlers

The library is fully compatible with modern build tools:

  • Vite: Works out of the box with ESM imports
  • Webpack 5: Full support with tree-shaking
  • Rollup: Native compatibility
  • esbuild: Full ESM support
  • Parcel: Zero-config support
  • Turbopack: Next.js 13+ compatible

Module Formats

  • ESM (dist/stacked-area-chart.esm.js): For modern bundlers and browsers
  • UMD (dist/stacked-area-chart.umd.js): For CDN usage and legacy environments
  • TypeScript (dist/index.d.ts): Full type definitions with source maps

Tree-Shaking

The library is marked with sideEffects: ["*.css"] in package.json, enabling optimal tree-shaking in modern bundlers. Only import what you use:

// Only imports the chart class and types used
import {StackedAreaChart, type ChartConfig} from 'energy-visualization-stacked-area-chart';

Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Clone your fork
  3. Create a feature branch: git checkout -b feature/energy-analysis
  4. Add tests: Ensure new features have test coverage
  5. Run the test suite: npm test
  6. Submit a pull request: Include description of changes

Development Guidelines

  • TypeScript: All code must be strictly typed
  • Testing: Maintain 90%+ test coverage
  • Energy Focus: Features should enhance energy data visualization
  • Performance: Consider impact on large datasets
  • Documentation: Update README for new features

License

MIT License. See LICENSE file for details.


Developed by the Research Computing Center (RCC), University of Chicago