A flexible and customizable Gantt chart library built with React.
- Interactive timeline visualization with drag and drop functionality
- Customizable views: Monthly, Quarterly, and Yearly views
- Collapsible hierarchical data structure support
- Progress indicators for tasks
- Zoom in/out capability
- Responsive design with customizable styling
- TypeScript support
npm install react-gantt-chart-adv-msp
or
yarn add react-gantt-chart-adv-msp
import React from 'react';
import { GanttChart, timeFrameSetting } from 'react-gantt-chart-adv-msp';
import 'react-gantt-chart-adv-msp/style.css'; // Don't forget to import the styles!
const App = () => {
// Define your columns
const columns = {
id: { name: 'ID', show: false },
name: { name: 'Task', show: true },
start: { name: 'Start Date', show: true },
end: { name: 'End Date', show: false },
};
// Define your rows (tasks)
const rows = [
{
id: 1,
name: 'Project Phase 1',
start: '2025-01-01T00:00:00Z',
end: '2025-03-31T00:00:00Z',
currentProgress: 75,
maxProgress: 100,
showProgressIndicator: {
showLabelOnGanttBar: true,
showLabelOnSideBar: true,
showProgressBar: true,
},
children: [
{
id: 2,
name: 'Task 1',
start: '2025-01-01T00:00:00Z',
end: '2025-01-15T00:00:00Z',
isLocked: false, // When true, task cannot be moved
},
{
id: 3,
name: 'Task 2',
start: '2025-01-16T00:00:00Z',
end: '2025-02-15T00:00:00Z',
highlight: true, // Highlights the task with a different color
},
],
},
];
// Function to handle row selection
const handleRowSelect = row => {
console.log('Selected row:', row);
};
return (
<div style={{ height: '500px' }}>
<GanttChart
columns={columns}
rows={rows}
defaultView={timeFrameSetting.monthly}
showSidebar={true}
getSelectedRow={handleRowSelect}
/>
</div>
);
};
export default App;
Prop | Type | Required | Default | Description |
---|---|---|---|---|
rows |
Row[] |
Yes | - | Array of row (task) data |
columns |
Column |
Yes | - | Column configuration |
showSidebar |
boolean |
No | true |
Toggle sidebar visibility |
defaultView |
TimeFrameSettingType |
No | monthly |
Default timeline view |
getSelectedRow |
(row: Row) => void |
No | - | Callback for row selection |
ButtonContainer |
React.FC |
No | - | Custom component to add action buttons |
className |
string |
No | - | Custom CSS class for additional styling |
Each row object requires these properties:
interface Row {
id: string | number; // Unique identifier
name: string; // Task name
start: string; // Start date in ISO format
end: string; // End date in ISO format
// Optional properties
highlight?: boolean; // Highlight the row/task
isLocked?: boolean; // Prevent dragging when true
currentProgress?: number; // Current progress value
maxProgress?: number; // Maximum progress value
showProgressIndicator: {
// Progress indicator settings
showLabelOnSideBar: false;
showLabelOnGanttBar: true;
showProgressBar: true;
};
progressIndicatorLabel?: string; // Custom label for progress indicator
children?: Row[]; // Child tasks
}
interface Column {
id: {
name: string;
show: boolean;
};
name: {
name: string;
show: boolean;
};
start: {
name: string;
show: boolean;
};
end: {
name: string;
show: boolean;
};
[key: string]: {
name: string;
show: boolean;
};
}
The package provides several predefined timeline views:
import { timeFrameSetting } from 'react-gantt-chart-adv-msp';
// Available views
const { monthly, yearly, quarterMonth, quarterYear } = timeFrameSetting;
You can programmatically control zoom level:
import { zoomIn, zoomOut } from 'react-gantt-chart-adv-msp';
// Usage
<button onClick={zoomIn}>Zoom In</button>
<button onClick={zoomOut}>Zoom Out</button>
You can override the default styles by providing a className prop and defining custom CSS variables:
.my-gantt-style {
--gantt-sidebar-width-fr: 0.3fr;
--gantt-bar-default-background: #3498db;
--gantt-bar-highlight-background: #2ecc71;
--gantt-sidebar-transition-duration: 0.3s;
}
Then apply the custom class:
<GanttChart className='my-gantt-style' {...otherProps} />
Below are some of the CSS variables that can be customized:
:root {
/* Layout */
--gantt-sidebar-width-fr: 0.2fr;
--gantt-timeline-width-fr: 1fr;
--gantt-global-border-color: lightGray;
--gantt-sidebar-transition-duration: 0.05s;
/* Data panel */
--gantt-data-panel-header-background: #f0f0f0;
--gantt-data-panel-header-font-weight: 600;
--gantt-data-panel-header-font-size: 0.9em;
--gantt-data-panel-row-background: #f9f9f9;
--gantt-data-panel-row-font-size: 0.9em;
--gantt-data-panel-row-font-weight: 400;
/* Timeline headers */
--gantt-primary-header-background: #f0f0f0;
--gantt-primary-header-font-weight: 500;
--gantt-primary-header-font-size: 0.8em;
--gantt-secondary-header-background: #f0f0f0;
--gantt-secondary-header-font-weight: 400;
--gantt-secondary-header-font-size: 0.8em;
/* Gantt bar */
--gantt-bar-text-color: white;
--gantt-bar-text-font-size: 0.9em;
--gantt-bar-text-font-weight: 400;
--gantt-bar-default-background: #4169e1;
--gantt-bar-highlight-background: #32de84;
--gantt-bar-boxShadow-hover: 0 2px 4px rgba(0, 0, 0, 0.2);
--gantt-bar-progress-text-color: white;
--gantt-bar-progress-text-font-size: 0.9em;
--gantt-bar-progress-text-font-weight: 400;
--gantt-bar-progress-indicator-background: rgba(41, 185, 106, 0.6);
--gantt-bar-resize-handle-background: rgba(0, 0, 0, 0.2);
--gantt-bar-resize-handle-width: 8px;
}
You can add custom action buttons to each row:
const ButtonContainer = () => {
return (
<div style={{ display: 'flex', gap: '3px' }}>
<button onClick={() => console.log('Add clicked')}>
<span>+</span>
</button>
<button onClick={() => console.log('Delete clicked')}>
<span>-</span>
</button>
</div>
);
};
<GanttChart
// other props
ButtonContainer={ButtonContainer}
/>;