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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@aardpro/ganttable

v1.4.0

Published

A powerful and customizable Gantt chart library built with D3.js and TypeScript

Readme

@aardpro/ganttable

A powerful and customizable Gantt chart library built with D3.js and TypeScript.

Features

  • 📊 Interactive Gantt Charts: Rich, interactive timeline visualization
  • 🎨 Customizable Themes: Flexible color schemes and styling
  • 🌳 Hierarchical Data: Support for nested tasks and subtasks
  • 📅 Flexible Date Handling: Support for various date formats and ranges
  • 🔗 Dependencies: Visual representation of task dependencies
  • 📱 Responsive Design: Works on desktop and mobile devices
  • High Performance: Optimized for large datasets

Gantt Chart Example

Installation

npm install @aardpro/ganttable
# or
yarn add @aardpro/ganttable
# or
pnpm add @aardpro/ganttable

Quick Start

import { GanttTable } from '@aardpro/ganttable';
import type { IGanttNode } from '@aardpro/ganttable';

const data: IGanttNode[] = [
  {
    id: '1',
    label: 'Project Planning',
    start_date: new Date('2024-01-01'),
    end_date: new Date('2024-01-15'),
    budget: 10000,
    cost: 8000,
    progress: 75,
    dependencies: [],
    is_milestone: false,
    children: [
      {
        id: '1.1',
        label: 'Research Phase',
        start_date: new Date('2024-01-01'),
        end_date: new Date('2024-01-05'),
        budget: 3000,
        cost: 2500,
        progress: 100,
        dependencies: [],
        is_milestone: false
      }
    ]
  }
];

const gantt = new GanttTable({
  target: document.getElementById('gantt-container'),
  data: data,
  colors: {
    tableHeaderBackground: '#f5f5f5',
    ganttBarBackground: '#a0c4ff',
    ganttBarProgress: '#4a90e2'
  }
});

API Reference

GanttTable

Constructor

new GanttTable(params: GanttTableParams)

Parameters

interface GanttTableParams {
  target: HTMLElement;           // Target container element
  data: IGanttNode[];             // Array of IGanttNode objects
  tableHeaderOptions?: ITableHeaderOption[]; // Custom column configuration
  expandedAll?: boolean;        // Expand all nodes by default
  showAdd?: boolean;            // Show add buttons
  showAction?: boolean;         // Show action column
  colors?: IGanttTableColorScheme; // Custom color scheme
  timeUnit?: IGanttTimeUnit;    // Time axis unit (default 'week')
  showGantt?: boolean;           // Show Gantt chart area (default: true)
  
  // Callbacks
  cellMenu?: (params: { row: IGanttNode; field: string; menu: HTMLElement; ptr?: { x: number; y: number; w: number; h: number } }) => void;
  rowMenu?: (params: { row: IGanttNode; menu: HTMLElement }) => void;
  askAdd?: (params: { row?: IGanttNode }) => void;
}

Methods

capture

Capture and download the rendered content as a PNG image.

capture(
  mode?: 'table' | 'gantt' | 'total',
  params?: { scale?: number; quality?: number; filename?: string; background?: string }
): Promise<void>
  • mode:
    • table — export only the table area
    • gantt — export only the gantt area
    • total — export both table and gantt (default)
  • scale (default 2) — pixel density multiplier for sharper export
  • quality (default 0.92) — kept for compatibility; browsers may ignore for PNG
  • filename (default ganttable-{mode}.png) — output file name
  • background (default #ffffff) — canvas background fill color

Example usages:

// Export both table and gantt
instance.capture('total', { scale: 2, quality: 0.92, filename: 'export-total.png' });

// Export only table
instance.capture('table', { scale: 2, filename: 'export-table.png' });

// Export only gantt
instance.capture('gantt', { scale: 3, filename: 'export-gantt.png' });

Demo buttons in the playground (src/main.ts) are bound to:

  • 下载总览图capture('total', { scale: 2 })
  • 下载表格capture('table', { scale: 2 })
  • 下载甘特图capture('gantt', { scale: 2 })

IGanttNode

interface IGanttNode {
  id: string;                    // Unique identifier
  pid?: string;                 // Parent ID
  label: string;                // Task name
  start_date: Date;             // Planned start date
  end_date: Date;               // Planned end date
  actual_start_date?: Date;     // Actual start date
  actual_end_date?: Date;       // Actual end date
  budget: number;               // Planned budget
  actual_budget?: number;       // Actual budget
  cost: number;                 // Planned cost
  actual_cost?: number;         // Actual cost
  progress: number;             // Progress percentage (0-100)
  dependencies: string[];       // Array of dependent task IDs
  is_milestone: boolean;        // Is this a milestone
  children?: IGanttNode[];       // Child tasks
  is_expanded?: boolean;        // Is node expanded
  level?: number;               // Tree level (auto-calculated)
}

Color Scheme

interface IGanttTableColorScheme {
  tableHeaderBackground?: string;
  tableBorder?: string;
  tableCellBackground?: string;
  ganttBarBackground?: string;
  ganttBarProgress?: string;
  ganttConnectionLine?: string;
  highlightOverlay?: string;
  textPrimary?: string;
  textSecondary?: string;
  textInverse?: string;
  iconColor?: string;
  milestoneColor?: string;
  // NEW: Actual duration overlay colors
  actualDueColor?: string;     // Default: #22c55e (on-time/early)
  actualDelayColor?: string;   // Default: #ef4444 (delay)
}

Actual Duration Overlay

  • When both actual_start_date and actual_end_date are present for a task, the chart renders a thin overlay bar within the main Gantt bar to visualize the actual duration.
  • Color logic:
    • actual_end_date > end_date → uses actualDelayColor (default #ef4444).
  • actual_end_dateend_date → uses actualDueColor (default #22c55e).
  • You can customize these via colors.actualDueColor and colors.actualDelayColor.

Time Unit Configuration

  • Use timeUnit to control the granularity of the time axis. Default is week.
  • Range extension by unit:
    • day: extends ±1 day
    • week: extends ±7 days
    • month: extends ±1 month
    • season (quarter): extends ±3 months
  • Axis label rules by unit:
    • day: show M/D (month start bold), other days DD
    • week: show MM/DD
    • month: show Chinese month names 一月 … 十二月
    • season: show Q1, Q2, Q3, Q4
  • Pixel density (approximate width per unit):
    • day: 36px
    • week: 80px
    • month: 120px
    • season: 180px
  • Example:
const gantt = new GanttTable({
  target: document.getElementById('gantt'),
  data: ganttData,
  timeUnit: 'day', // daily axis with M/D for month start, DD for other days
  showGantt: true, // set to false to hide the Gantt area initially
});

// Switch time unit without recreating the instance gantt.update({ timeUnit: 'week' });

Demo Selector

  • The demo page includes a time unit selector in src/main.ts bound to div#time-unit-selector.
  • Changing the selector updates the instance via gantt.update({ timeUnit }) (day, week, month, season).
  • The demo also includes a Gantt visibility toggle checkbox in div#toggle-gantt and a status display in div#gantt-status.

Show/Hide Gantt

  • Visibility control:
    • showGantt (constructor param): controls initial visibility; default true.
    • ganttStatus (instance property): current visibility state (true shown, false hidden).
    • toggleGantt(show: boolean) (instance method): programmatically toggle visibility.
// Create instance with initial hidden Gantt area
const gantt = new GanttTable({
  target: document.getElementById('gantt'),
  data: ganttData,
  showGantt: false,
});

// Later, show the Gantt area
gantt.toggleGantt(true);

// Hook up to a checkbox
const checkbox = document.getElementById('toggleGanttCheckbox') as HTMLInputElement;
checkbox.addEventListener('change', () => {
  gantt.toggleGantt(checkbox.checked);
  console.log('Gantt visible:', gantt.ganttStatus);
});

Usage Examples

Basic Usage

import { GanttTable } from '@aardpro/ganttable';

const gantt = new GanttTable({
  target: document.getElementById('gantt'),
  data: ganttData
});

With Custom Configuration

const gantt = new GanttTable({
  target: document.getElementById('gantt'),
  data: ganttData,
  tableHeaderOptions: [
    { field: 'label', label: 'Task', width: 200 },
    { field: 'start_date', label: 'Start', width: 100 },
    { field: 'end_date', label: 'End', width: 100 },
    { field: 'progress', label: 'Progress', width: 80 }
  ],
  colors: {
    ganttBarBackground: '#4CAF50',
    ganttBarProgress: '#2E7D32'
  },
  expandedAll: true
});

With Event Handlers

const gantt = new GanttTable({
  target: document.getElementById('gantt'),
  data: ganttData,
  askAdd: ({ row }) => {
    console.log('Add new task under:', row?.label);
  },
  cellMenu: ({ row, field, menu, ptr }) => {
    // Custom cell menu implementation
    menu.innerHTML = `
      <div class="menu-item">Edit ${field}</div>
      <div class="menu-item">Delete</div>
    `;
    // Access the clicked cell's viewport rect if needed
    if (ptr) {
      console.log('Cell rect:', ptr);
    }
  }
});

Browser Support

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

License

MIT License - see LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Changelog

1.0.0

  • Initial release
  • Basic Gantt chart functionality
  • Hierarchical task support
  • Customizable themes
  • Interactive features