ts-gantt-engine
A highly customizable, lightweight Gantt chart engine written entirely in TypeScript and rendered using HTML Canvas.
Built for developers who need powerful Gantt chart functionality without the bloat. Features a task grid, interactive timeline, relation lines, multiple timeline comparisons, and extensive customization options—all in a lightweight package with minimal dependencies.
🚀 Live Demo
🔗 Demo URL
https://tekula-hemanth-reddy.github.io/ts-gantt-engine-demo/
✨ Features
🎨 Fully Customizable
- TypeScript-first design for type safety and better developer experience
- Canvas-powered rendering for maximum performance and flexibility
- Extensive styling options: colors, fonts, dimensions, and more
📊 Dual-Component Architecture
- Task Grid — Vertical scrolling with hierarchical task display
- Gantt Timeline — Bi-directional scrolling (horizontal & vertical) with date-based visualization
🌲 Tree Structure Support
- Parent-child task hierarchy
- Smooth expand/collapse animations
- Visual indicators for nested relationships
📈 Multiple Timeline Support
- Main timeline for primary task duration
- Comparison timelines for planned vs actual, baseline, forecast, etc.
- Support for multiple duration types: original, planned, updated, actual, critical, baseline, forecast, or custom types
🔗 Task Relations
Draw and visualize four types of task dependencies with customizable colors:
- FS (Finish-to-Start)
- SF (Start-to-Finish)
- SS (Start-to-Start)
- FF (Finish-to-Finish)
🎯 Rich Interactions
- Tooltip support for detailed task information
- Click event emitters for taskbar interactions
- Responsive mouse tracking and selection
⚡ Lightweight & Fast
- Only one dependency:
moment-timezone
- Minimal bundle size
- Optimized canvas rendering
📦 Installation
npm
npm install ts-gantt-engine
pnpm
pnpm add ts-gantt-engine
yarn
yarn add ts-gantt-engine
🚀 Quick Start
canvas {
display: block;
width: 100%;
height: 100%;
}
import { GanttEngine } from "ts-gantt-engine";
const canvas = document.getElementById("gantt") as HTMLCanvasElement;
const engine = new GanttEngine(
canvas,
"day",
(data) => {
console.log("Task clicked:", data);
}
);
const headers = [
{ hId: "1", hName: "Task Name" },
{ hId: "2", hName: "Status" },
];
const tasks = [
{
pId: "1",
pName: "Project Planning",
pMainTimeline: {
gId: "main",
gName: "Main Timeline",
gClass: "#9B59B6",
gStart: new Date("2024-01-01"),
gEnd: new Date("2024-01-04"),
gPercentage: 75,
},
pTimelines: [
{
gId: "planned",
gName: "Planned",
gClass: "#E8DAEF",
gStart: new Date("2024-01-01"),
gEnd: new Date("2024-01-05"),
gPercentage: 0,
},
],
pRelation: [],
pData: { "1": "Project Planning", "2": "In Progress" },
},
{
pId: "2",
pName: "Design Phase",
pMainTimeline: {
gId: "main",
gName: "Main Timeline",
gClass: "#3498DB",
gStart: new Date("2024-01-03"),
gEnd: new Date("2024-01-06"),
gPercentage: 50,
},
pTimelines: [],
pParent: "1",
pRelation: [{ pTarget: "1", pType: "FS" }],
pData: { "1": "Design Phase", "2": "Not Started" },
},
];
engine.render(headers, tasks, {
columnWidth: 100,
headerHeight: 50,
headerBg: '#F4F5F8',
canvasBg: '#fff',
fontColor: '#1F2329',
lineColor: '#D2D8E3',
font: '14px Arial',
boxHeight: 50,
barHeight: 20,
barHorizontalResidue: 5,
barVerticalResidue: 5,
curveRadius: 3,
});
const relationColors = {
FS: "#2ECC71",
SF: "#E74C3C",
SS: "#3498DB",
FF: "#F39C12",
};
engine.render(headers, tasks, options, relationColors);
engine.destroy();
📖 API Reference
GanttEngine
Constructor
new GanttEngine(
canvas: HTMLCanvasElement,
format: "day" | "week" | "month" | "quarter" | "year",
onTaskClick?: (data: GanttTask) => void
)
Methods
Renders the Gantt chart with the provided data.
engine.render(
headers: GanttHeader[],
tasks: GanttTask[],
options: GanttOptions,
relationColors?: RelationColors
): void
setFormat(format)
Changes the time scale format.
engine.setFormat(format: "day" | "week" | "month" | "quarter" | "year"): void
clearScreen()
Clears the canvas.
engine.clearScreen(): void
destroy()
Stops drawing chart and destroy the canvas.
engine.destroy(): void
getCanvas()
Returns the canvas element.
engine.getCanvas(): HTMLCanvasElement
getBounds()
Returns the canvas dimensions.
engine.getBounds(): number[]
📝 Type Definitions
GanttTask
interface GanttTask {
pId: string;
pName: string;
pMainTimeline: GanttDuration;
pTimelines: GanttDuration[];
pParent?: string;
pRelation: {
pTarget: string;
pType: "FF" | "SF" | "FS" | "SS";
}[];
pData: { [key: string]: string };
}
GanttDuration
interface GanttDuration {
gId: GanttDurationType;
gName: string;
gClass: string;
gStart?: Date;
gEnd?: Date;
gPercentage: number;
}
type GanttDurationType =
| "main"
| "original"
| "planned"
| "updated"
| "actual"
| "critical"
| "baseline"
| "forecast"
| string;
interface GanttHeader {
hId: string;
hName: string;
}
GanttOptions
interface GanttOptions {
columnWidth?: number;
headerHeight?: number;
headerBg?: string;
canvasBg?: string;
fontColor?: string;
lineColor?: string;
font?: string;
boxHeight?: number;
barHeight?: number;
barHorizontalResidue?: number;
barVerticalResidue?: number;
curveRadius?: number;
}
RelationColors
interface RelationColors {
FS: string;
SF: string;
SS: string;
FF: string;
}
🎨 Customization Examples
Dark Theme
engine.render(headers, tasks, {
headerBg: "#1e1e1e",
canvasBg: "#2d2d2d",
fontColor: "#ffffff",
lineColor: "#404040",
font: "14px 'Segoe UI'",
});
Compact View
engine.render(headers, tasks, {
columnWidth: 80,
headerHeight: 35,
boxHeight: 35,
barHeight: 15,
font: "12px Arial",
});
Custom Relation Colors
const relationColors = {
FS: "#27AE60",
SF: "#E67E22",
SS: "#2980B9",
FF: "#8E44AD",
};
engine.render(headers, tasks, options, relationColors);
Planned vs Actual Comparison
const tasks = [
{
pId: "1",
pName: "Development",
pMainTimeline: {
gId: "actual",
gName: "Actual Progress",
gClass: "#2ECC71",
gStart: new Date("2024-01-01"),
gEnd: new Date("2024-01-10"),
gPercentage: 60,
},
pTimelines: [
{
gId: "planned",
gName: "Planned Schedule",
gClass: "#BDC3C7",
gStart: new Date("2024-01-01"),
gEnd: new Date("2024-01-08"),
gPercentage: 0,
},
],
pRelation: [],
pData: { "1": "Development", "2": "In Progress" },
},
];
🗺️ Roadmap
🔜 Coming Soon
- Bi-directional scrolling for Task Grid — Horizontal scrolling support
- Drag to resize tasks — Interactive taskbar duration adjustment
- Hover highlighting — Highlight tasks and relations on mouse hover
- Zoom controls — Dynamic time scale adjustment
- Export functionality — Save charts as images or PDF
💡 Use Cases
- Project management dashboards
- Resource planning tools
- Production scheduling systems
- Event timeline visualization
- Workflow management applications
- Planned vs Actual tracking
- Baseline comparison and variance analysis
🤝 Contributing
Contributions are welcome! Please feel free to submit issues or pull requests.
📄 License
[MIT]
🔗 Links
📧 Support
For questions, issues, or feature requests, please open an issue on GitHub or reach out directly:
"Learn to fly, go up high, till you reach the sky."