How can I help you?
Column Pinning (Frozen) in React Gantt Chart Component
31 Jan 202624 minutes to read
The Syncfusion® React Gantt Chart component provides a frozen columns feature that keeps selected columns fixed while scrolling horizontally through large datasets. This functionality ensures that critical information remains visible at all times, improving readability and user experience. By maintaining key columns in view, it simplifies navigation and makes referencing important data points easier when working with extensive project details.
To enable frozen columns, use the frozenColumns property in the Gantt Chart component.
In the following example, the frozenColumns property is set to 2, which keeps the first two columns fixed on the left while the remaining columns can be scrolled horizontally.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective, Inject, Freeze } from '@syncfusion/ej2-react-gantt';
import { GanttData } from './datasource';
function App() {
const taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
endDate: 'EndDate',
dependency: 'Predecessor',
progress: 'Progress',
parentID: 'ParentID'
};
const labelSettings = {
taskLabel: 'Progress'
};
const splitterSettings = {
position: '65%'
};
const gridLines = 'Both';
return (
<GanttComponent
height="430px"
dataSource={GanttData}
taskFields={taskSettings}
labelSettings={labelSettings}
frozenColumns={2}
treeColumnIndex={1}
splitterSettings={splitterSettings}
gridLines={gridLines}
allowSelection={false}
>
<ColumnsDirective>
<ColumnDirective field="TaskID" headerText="Task ID" textAlign="Right" width="90" />
<ColumnDirective field="TaskName" headerText="Task Name" textAlign="Left" width="290" />
<ColumnDirective field="StartDate" headerText="Start Date" textAlign="Right" width="120" />
<ColumnDirective field="Duration" headerText="Duration" textAlign="Right" width="90" />
<ColumnDirective field="EndDate" headerText="End Date" textAlign="Right" width="120" />
<ColumnDirective field="Progress" headerText="Progress" textAlign="Left" width="120" />
<ColumnDirective field="Predecessor" headerText="Predecessor" textAlign="Left" width="120" />
</ColumnsDirective>
<Inject services={[ Freeze ]} />
</GanttComponent>
);
}
ReactDOM.render(<App />, document.getElementById('root'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective, Inject, SplitterSettingsModel, GridLine, Freeze } from '@syncfusion/ej2-react-gantt';
import { GanttData } from './datasource';
function App() {
const taskSettings: object = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
endDate: 'EndDate',
dependency: 'Predecessor',
progress: 'Progress',
parentID: 'ParentID'
};
const labelSettings: object = {
taskLabel: 'Progress'
};
const splitterSettings: SplitterSettingsModel = {
position: '65%'
};
const gridLines: GridLine = 'Both';
return (
<GanttComponent
height="430px"
dataSource={GanttData}
taskFields={taskSettings}
labelSettings={labelSettings}
frozenColumns={2}
treeColumnIndex={1}
splitterSettings={splitterSettings}
gridLines={gridLines}
allowSelection={false}
>
<ColumnsDirective>
<ColumnDirective field="TaskID" headerText="Task ID" textAlign="Right" width="90" />
<ColumnDirective field="TaskName" headerText="Task Name" textAlign="Left" width="290" />
<ColumnDirective field="StartDate" headerText="Start Date" textAlign="Right" width="120" />
<ColumnDirective field="Duration" headerText="Duration" textAlign="Right" width="90" />
<ColumnDirective field="EndDate" headerText="End Date" textAlign="Right" width="120" />
<ColumnDirective field="Progress" headerText="Progress" textAlign="Left" width="120" />
<ColumnDirective field="Predecessor" headerText="Predecessor" textAlign="Left" width="120" />
</ColumnsDirective>
<Inject services={[Freeze]} />
</GanttComponent>
);
}
ReactDOM.render(<App />, document.getElementById('root'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/33.2.3/tailwind3.css" rel="stylesheet" type="text/css" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Freeze particular columns
The Syncfusion® React Gantt provides a feature that enables freezing specific columns, significantly enhancing data visibility and improving the user experience. The isFrozen property is used at the column level to freeze a specific column at any desired index on the left side, offering flexibility in managing which columns are frozen.
To freeze a particular column in the Gantt, set the isFrozen property of the column to true.
The following example demonstrates how to freeze a particular column in the Gantt using the isFrozen property.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective, Inject, Freeze } from '@syncfusion/ej2-react-gantt';
import { GanttData } from './datasource';
function App() {
const taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
endDate: 'EndDate',
progress: 'Progress',
parentID: 'ParentID'
};
const splitterSettings = {
position: '65%'
};
const labelSettings = {
taskLabel: 'Progress',
rightLabel: 'TaskName'
};
return (
<GanttComponent
height="430px"
dataSource={GanttData}
taskFields={taskSettings}
treeColumnIndex={1}
splitterSettings={splitterSettings}
allowSelection={false}
gridLines="Both"
labelSettings={labelSettings}
>
<ColumnsDirective>
<ColumnDirective field="TaskID" headerText="Task ID" isFrozen={true} />
<ColumnDirective field="TaskName" headerText="Task Name" width="220" isFrozen={true} />
<ColumnDirective field="StartDate" headerText="Start Date" />
<ColumnDirective field="Duration" headerText="Duration" />
<ColumnDirective field="Progress" headerText="Progress" />
<ColumnDirective field="Status" headerText="Status" isFrozen={true} />
</ColumnsDirective>
<Inject services={[ Freeze]} />
</GanttComponent>
);
}
ReactDOM.render(<App />, document.getElementById('root'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective, Inject, SplitterSettings, Freeze } from '@syncfusion/ej2-react-gantt';
import { GanttData } from './datasource';
function App() {
const taskSettings: object = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
endDate: 'EndDate',
progress: 'Progress',
parentID: 'ParentID'
};
const splitterSettings: SplitterSettings = {
position: '65%'
};
const labelSettings: object = {
taskLabel: 'Progress',
rightLabel: 'TaskName'
};
return (
<GanttComponent
height="430px"
dataSource={GanttData}
taskFields={taskSettings}
treeColumnIndex={1}
splitterSettings={splitterSettings}
allowSelection={false}
gridLines="Both"
labelSettings={labelSettings}
>
<ColumnsDirective>
<ColumnDirective field="TaskID" headerText="Task ID" isFrozen={true} />
<ColumnDirective field="TaskName" headerText="Task Name" width="220" isFrozen={true} />
<ColumnDirective field="StartDate" headerText="Start Date" />
<ColumnDirective field="Duration" headerText="Duration" />
<ColumnDirective field="Progress" headerText="Progress" />
<ColumnDirective field="Status" headerText="Status" isFrozen={true} />
</ColumnsDirective>
<Inject services={[ Freeze ]} />
</GanttComponent>
);
}
ReactDOM.render(<App />, document.getElementById('root'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/33.2.3/tailwind3.css" rel="stylesheet" type="text/css" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Freeze direction
In the Syncfusion® React Gantt, the freeze direction feature allows you to position frozen columns either to the left, right, or in a fixed position, while still allowing the remaining columns to be horizontally movable.
To achieve this, the column.freeze property can be utilized. This property is used to specify the freeze direction for individual columns.
The types of the column.freeze directions:
-
Left: When the
column.freezeproperty is set to Left, specific columns will be frozen on the left side. -
Right: When the
column.freezeproperty is set to Right, certain columns will be frozen on the right side. -
Fixed: The Fixed direction locks a column at a fixed position within the Gantt columns. This ensures that the column is always visible during horizontal scroll.
In the following example, the TaskID column is frozen on the left side, the resources column is frozen on the right side and the Progress column is frozen on the fixed of the content table.
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective, Inject, Freeze } from '@syncfusion/ej2-react-gantt';
import { GanttData, resourceCollection } from './datasource';
function App() {
const taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
endDate: 'EndDate',
dependency: 'Predecessor',
progress: 'Progress',
parentID: 'ParentID',
resourceInfo: 'Resources'
};
const splitterSettings = {
position: '65%'
};
const labelSettings = {
taskLabel: 'Progress'
};
const resourceFields = {
id: 'resourceId',
name: 'resourceName'
};
return (
<GanttComponent
height="430px"
dataSource={GanttData}
taskFields={taskSettings}
treeColumnIndex={1}
splitterSettings={splitterSettings}
gridLines="Both"
resources={resourceCollection}
resourceFields={resourceFields}
labelSettings={labelSettings}
>
<ColumnsDirective>
<ColumnDirective field="TaskID" headerText="Task ID" freeze="Left" />
<ColumnDirective field="TaskName" headerText="Task Name" width="200" />
<ColumnDirective field="StartDate" headerText="Start Date" width="130" />
<ColumnDirective field="Duration" headerText="Duration" width="110" />
<ColumnDirective field="EndDate" headerText="End Date" width="130" />
<ColumnDirective field="Progress" headerText="Progress" width="110" freeze="Fixed" />
<ColumnDirective field="Predecessor" headerText="Dependency" width="120" />
<ColumnDirective field="Resources" headerText="Assignee" freeze="Right" />
</ColumnsDirective>
<Inject services={[ Freeze ]} />
</GanttComponent>
);
}
ReactDOM.render(<App />, document.getElementById('root'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective, Inject, SplitterSettings, Freeze } from '@syncfusion/ej2-react-gantt';
import { GanttData, resourceCollection } from './datasource';
function App() {
const taskSettings: object = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
endDate: 'EndDate',
dependency: 'Predecessor',
progress: 'Progress',
parentID: 'ParentID',
resourceInfo: 'Resources'
};
const splitterSettings: SplitterSettings = {
position: '65%'
};
const labelSettings: object = {
taskLabel: 'Progress'
};
const resourceFields: object = {
id: 'resourceId',
name: 'resourceName'
};
return (
<GanttComponent
height="430px"
dataSource={GanttData}
taskFields={taskSettings}
treeColumnIndex={1}
splitterSettings={splitterSettings}
gridLines="Both"
resources={resourceCollection}
resourceFields={resourceFields}
labelSettings={labelSettings}
>
<ColumnsDirective>
<ColumnDirective field="TaskID" headerText="Task ID" freeze="Left" />
<ColumnDirective field="TaskName" headerText="Task Name" width="200" />
<ColumnDirective field="StartDate" headerText="Start Date" width="130" />
<ColumnDirective field="Duration" headerText="Duration" width="110" />
<ColumnDirective field="EndDate" headerText="End Date" width="130" />
<ColumnDirective field="Progress" headerText="Progress" width="110" freeze="Fixed" />
<ColumnDirective field="Predecessor" headerText="Dependency" width="120" />
<ColumnDirective field="Resources" headerText="Assignee" freeze="Right" />
</ColumnsDirective>
<Inject services={[ Freeze ]} />
</GanttComponent>
);
}
ReactDOM.render(<App />, document.getElementById('root'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/33.2.3/tailwind3.css" rel="stylesheet" type="text/css" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
</style>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Change default frozen line color
The frozen line borders of frozen columns in the Syncfusion® React Gantt Chart component can be customized by applying custom CSS styles to the respective frozen columns. This allows you to change the border color of left, right, and fixed frozen columns to match your application’s design and theme.
To change the default frozen line color, use the following CSS class names and apply the desired border color:
For left frozen columns:
.e-gantt .e-leftfreeze.e-freezeleftborder {
border-right-color: rgb(0, 255, 0) !important;
}For right frozen columns:
.e-gantt .e-rightfreeze.e-freezerightborder {
border-left-color: rgb(0, 0, 255) !important;
}For fixed frozen columns, both left and right borders need to be specified as mentioned below:
.e-gantt .e-leftfreeze.e-freezeleftborder {
border-right-color: rgb(0, 255, 0) !important;
}
.e-gantt .e-rightfreeze.e-freezerightborder {
border-left-color: rgb(0, 0, 255) !important;
}The following example demonstrates how to change the default frozen line color using CSS:
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective, Inject } from '@syncfusion/ej2-react-gantt';
import { GanttData } from './datasource';
function App() {
const taskSettings = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
endDate: 'EndDate',
dependency: 'Predecessor',
progress: 'Progress',
parentID: 'ParentID'
};
const splitterSettings = {
position: '65%'
};
return (
<GanttComponent
height="430px"
dataSource={GanttData}
taskFields={taskSettings}
treeColumnIndex={1}
splitterSettings={splitterSettings}
allowSelection={false}
gridLines="Both"
>
<ColumnsDirective>
<ColumnDirective field="TaskID" headerText="Task ID" freeze="Left" />
<ColumnDirective field="TaskName" headerText="Task Name" width="200" freeze="Left" />
<ColumnDirective field="StartDate" headerText="Start Date" />
<ColumnDirective field="Duration" headerText="Duration" />
<ColumnDirective field="EndDate" headerText="End Date" />
<ColumnDirective field="Progress" headerText="Progress" freeze="Right" />
<ColumnDirective field="Status" headerText="Status" />
</ColumnsDirective>
<Inject services={[]} />
</GanttComponent>
);
}
ReactDOM.render(<App />, document.getElementById('root'));import * as React from 'react';
import * as ReactDOM from 'react-dom';
import { GanttComponent, ColumnsDirective, ColumnDirective, Inject, Freeze } from '@syncfusion/ej2-react-gantt';
import { GanttData } from './datasource';
function App() {
const taskSettings: object = {
id: 'TaskID',
name: 'TaskName',
startDate: 'StartDate',
duration: 'Duration',
endDate: 'EndDate',
dependency: 'Predecessor',
progress: 'Progress',
parentID: 'ParentID'
};
const splitterSettings: object = {
position: '65%'
};
return (
<GanttComponent
height="430px"
dataSource={GanttData}
taskFields={taskSettings}
treeColumnIndex={1}
splitterSettings={splitterSettings}
allowSelection={false}
gridLines="Both"
>
<ColumnsDirective>
<ColumnDirective field="TaskID" headerText="Task ID" freeze="Left" />
<ColumnDirective field="TaskName" headerText="Task Name" width="200" freeze="Left" />
<ColumnDirective field="StartDate" headerText="Start Date" />
<ColumnDirective field="Duration" headerText="Duration" />
<ColumnDirective field="EndDate" headerText="End Date" />
<ColumnDirective field="Progress" headerText="Progress" freeze="Right" />
<ColumnDirective field="Status" headerText="Status" />
</ColumnsDirective>
<Inject services={[ Freeze ]} />
</GanttComponent>
);
}
ReactDOM.render(<App />, document.getElementById('root'));<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Gantt</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/33.2.3/tailwind3.css" rel="stylesheet" type="text/css" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.e-gantt .e-leftfreeze.e-freezeleftborder {
border-right-color: rgb(0, 255, 0) !important;
}
.e-gantt .e-rightfreeze.e-freezerightborder {
border-left-color: rgb(0, 0, 255) !important;
}
.e-gantt .e-leftfreeze.e-freezeleftborder {
border-right-color: rgb(0, 255, 0) !important;
}
.e-gantt .e-rightfreeze.e-freezerightborder {
border-left-color: rgb(0, 0, 255) !important;
}
</style>
</head>
<body>
<div id='root'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>Limitations
- Freeze Direction is not compatible with the isFrozen and frozenColumns properties.