Custom Task-List Columns
The task-list panel on the left side of the chart shows a configurable set of columns. Pass columnConfig to control which columns appear, in what order, and how wide they are. You can also add fully custom columns with a render function.
Built-in columns
ColumnKey | key string | Default shown | Description |
|---|---|---|---|
Name | 'name' | Yes | Task name |
StartTime | 'startTime' | Yes | Start date |
EndTime | 'endTime' | Yes | End date |
Duration | 'duration' | No | Computed working-day duration |
Progress | 'progress' | No | Completion percent as text |
ProgressRing | 'progressRing' | No | Circular progress indicator |
Wbs | 'wbs' | No | Work Breakdown Structure code |
Showing a subset of columns
const gantt = new ApexGantt(document.getElementById('chart'), {
series: tasks,
columnConfig: [
{ key: 'name', title: 'Task', minWidth: '200px', flexGrow: 3 },
{ key: 'startTime', title: 'Start', minWidth: '100px', flexGrow: 1 },
{ key: 'endTime', title: 'End', minWidth: '100px', flexGrow: 1 },
{ key: 'progress', title: 'Progress', minWidth: '80px', flexGrow: 1 },
],
})
ColumnListItem properties
| Property | Type | Description |
|---|---|---|
key | ColumnKey | string | Built-in key or any string for a custom column |
title | string | Column header text |
minWidth | string | CSS minimum width (e.g. '120px') |
flexGrow | number | Flex grow ratio; controls how extra space is distributed |
visible | boolean | When false, the column is hidden |
render | ColumnRenderer | Custom cell renderer (required for custom columns) |
accessor | (task) => unknown | Extracts the cell's underlying value — used by SVG export |
Adding WBS and duration
columnConfig: [
{ key: 'wbs', title: '#', minWidth: '50px', flexGrow: 0 },
{ key: 'name', title: 'Task', minWidth: '180px', flexGrow: 3 },
{ key: 'duration', title: 'Days', minWidth: '60px', flexGrow: 0 },
{ key: 'startTime', title: 'Start', minWidth: '100px', flexGrow: 1 },
{ key: 'endTime', title: 'End', minWidth: '100px', flexGrow: 1 },
{ key: 'progressRing', title: '', minWidth: '40px', flexGrow: 0 },
],
Custom column with a render function
The render function receives (ctx, el) where ctx is the render context and el is the pre-attached cell DOM element.
Return a string to have the library set it as innerHTML. Return void after mounting your own content into el. Return a cleanup function to unmount framework components when the cell is discarded.
const gantt = new ApexGantt(el, {
series: tasks,
columnConfig: [
{ key: 'name', title: 'Task', minWidth: '180px', flexGrow: 3 },
{ key: 'startTime',title: 'Start', minWidth: '100px', flexGrow: 1 },
{
key: 'status',
title: 'Status',
minWidth: '100px',
flexGrow: 1,
render: (ctx) => {
const { task } = ctx
const label =
task.progress === 100 ? 'Done' :
task.progress > 0 ? 'In Progress' :
'Not Started'
const color =
task.progress === 100 ? '#10B981' :
task.progress > 0 ? '#F59E0B' :
'#94A3B8'
return `
<span style="
display:inline-block;padding:2px 8px;border-radius:10px;
background:${color}22;color:${color};font-size:11px;font-weight:600;
">${label}</span>
`
},
accessor: (task) => task.progress,
},
],
})
Built-in avatars renderer
When tasks include an assignees array, use the built-in renderers.avatars factory to render stacked avatar chips without writing the DOM yourself:
import ApexGantt, { renderers } from 'apexgantt'
const gantt = new ApexGantt(el, {
series: [
{
id: 'task-1',
name: 'Design System',
startTime: '2024-03-01',
endTime: '2024-03-15',
progress: 60,
assignees: [
{ name: 'Alice Chen', avatarUrl: '/avatars/alice.jpg' },
{ name: 'Bob Patel', color: '#6366F1' },
{ name: 'Carol Smith', initials: 'CS', color: '#10B981' },
],
},
],
columnConfig: [
{ key: 'name', title: 'Task', minWidth: '180px', flexGrow: 3 },
{ key: 'startTime',title: 'Start', minWidth: '100px', flexGrow: 1 },
{
key: 'assigned',
title: 'Assigned',
minWidth: '120px',
flexGrow: 1,
render: renderers.avatars({
accessor: (task) => task.assignees,
max: 3, // show up to 3 avatars, then "+N"
size: 24, // diameter in px
overlap: 8, // how much each avatar overlaps the previous
}),
},
],
})
AvatarsRendererOptions
| Option | Type | Default | Description |
|---|---|---|---|
accessor | (task) => Assignee[] | Required | Returns the list of assignees for a task |
max | number | 4 | Max avatars shown; excess shown as +N |
size | number | 24 | Avatar diameter in pixels |
overlap | number | 8 | Overlap between adjacent avatars in pixels |
borderColor | string | '#FFFFFF' | Border around each avatar |
fallbackColor | string | — | Background for initials fallback when Assignee.color is not set |
Assignee fields
| Field | Type | Description |
|---|---|---|
name | string | Display name; used for alt text and initials source |
avatarUrl | string | Image URL — when set, renders an <img> |
initials | string | Override for the two-letter initials fallback |
color | string | Background color for the initials fallback |
React example
import { ApexGanttChart } from 'react-apexgantt'
import { renderers } from 'apexgantt'
import type { GanttUserOptions } from 'react-apexgantt'
const options: Omit<GanttUserOptions, 'series'> = {
columnConfig: [
{ key: 'name', title: 'Task', minWidth: '180px', flexGrow: 3 },
{ key: 'startTime',title: 'Start', minWidth: '100px', flexGrow: 1 },
{ key: 'endTime', title: 'End', minWidth: '100px', flexGrow: 1 },
{
key: 'status',
title: 'Status',
minWidth: '90px',
flexGrow: 1,
render: (ctx) => {
const pct = ctx.task.progress
const label = pct === 100 ? 'Done' : pct > 0 ? 'In Progress' : 'Not Started'
const color = pct === 100 ? '#10B981' : pct > 0 ? '#F59E0B' : '#94A3B8'
return `<span style="color:${color};font-size:11px;font-weight:600">${label}</span>`
},
},
{
key: 'assigned',
title: 'Team',
minWidth: '110px',
flexGrow: 1,
render: renderers.avatars({ accessor: (task) => task.assignees }),
},
],
}
export default function CustomColumnsGantt() {
return <ApexGanttChart tasks={tasks} options={options} height="500px" />
}
Vue example
<template>
<ApexGanttChart :tasks="tasks" :options="ganttOptions" height="500px" />
</template>
<script setup lang="ts">
import { renderers } from 'apexgantt'
import type { GanttUserOptions } from 'vue-apexgantt'
const ganttOptions: Partial<GanttUserOptions> = {
columnConfig: [
{ key: 'name', title: 'Task', minWidth: '180px', flexGrow: 3 },
{ key: 'startTime',title: 'Start', minWidth: '100px', flexGrow: 1 },
{ key: 'endTime', title: 'End', minWidth: '100px', flexGrow: 1 },
{ key: 'progress', title: 'Progress',minWidth: '80px', flexGrow: 1 },
{
key: 'assigned',
title: 'Team',
minWidth: '110px',
flexGrow: 1,
render: renderers.avatars({ accessor: (task) => task.assignees, max: 3 }),
},
],
}
</script>