Blazorise Gantt component

Build timeline-driven planning experiences with a synchronized tree and timeline view.

The Gantt component is designed for project planning use cases where tasks have hierarchy, dates, duration, and progress. It supports declarative columns, built-in editing, keyboard and mouse interactions, and template-based customization.

To use the Gantt component, install the Blazorise.Gantt package first.

Installation

NuGet

Install extension from NuGet.
Install-Package Blazorise.Gantt

Imports

In your main _Imports.razor add:
@using Blazorise.Gantt

Fundamentals

Data Model

Gantt<TItem> binds to your own model type through field mapping parameters such as IdField, StartField, and EndField. You can keep your existing model names and map them without creating a dedicated DTO.

Must-Have Fields

For most production scenarios, these are the fields you should map:

  • StartField and EndField: Required to render timeline bars. If either value is missing/unassigned, the item cannot be drawn on the timeline.
  • TitleField: Recommended for readable tree rows and task labels.
  • IdField: Strongly recommended for stable identity, selection/state behavior, and CRUD operations.
  • DurationField (optional): Used for duration column/editing. If not mapped, duration is calculated from StartField and EndField.
  • ProgressField (optional): Enables progress percentage in bars, columns, and the edit dialog slider.

Flat vs Hierarchical Data

Gantt supports both data shapes:

  • Flat data: One collection with IdField and ParentIdField. This is usually best for API-driven data.
  • Hierarchical data: Nested child collections mapped through ItemsField.
  • If both ParentIdField and ItemsField exist, Gantt uses flat mode by default. Set HierarchicalData="true" to force hierarchical mode.
  • If ItemsField exists and ParentIdField does not, hierarchical mode is used automatically.

Columns

Use GanttColumns and declarative column components to control field mapping, order, visibility, sorting, alignment, and templates. This keeps tree rendering explicit and easy to evolve as requirements grow.

Editing and Commands

Set Editable to enable built-in create, add-child, edit, and delete flows. Use command switches and CommandAllowed for role-based or item-based command rules.

Set UseInternalEditing="false" when you want Gantt to keep its command affordances but let your page own the modal and persistence flow through NewItemClicked, AddChildItemClicked, EditItemClicked, and DeleteItemClicked.

Examples

Flat Data Binding

Use the classic Id + ParentId model when your API already returns a flat task list.

Some columns are hidden by default so the timeline has more space; use the Column Picker in the toolbar to show them.

Apr 27 - May 03, 2026
Task
Start
Website redesign
Apr 28, 2026
Discovery
Apr 28, 2026
Implementation
May 02, 2026
Components
May 03, 2026
Accessibility pass
May 08, 2026
Launch
May 12, 2026
Mon 27
Tue 28
Wed 29
Thu 30
Fri 01
Sat 02
Sun 03
Website redesign
Discovery
Implementation
Components
<Gantt TItem="TaskItem"
       Data="@tasks"
       Date="@selectedDate"
       SelectedView="GanttView.Week"
       DurationField="Duration">
    <GanttColumns>
        <GanttColumn Field="Title" Title="Task" Expandable Width="Width.Px(220)" />
        <GanttColumn Field="Start" Width="Width.Px(130)" />
        <GanttColumn Field="End" Width="Width.Px(130)" Visible="false" />
        <GanttColumn Field="Duration" Width="Width.Px(90)" TextAlignment="TextAlignment.Center" Visible="false" />
    </GanttColumns>
    <GanttToolbar />
    <GanttViews>
        <GanttWeekView TimelineCellWidth="90" RowHeight="44" />
    </GanttViews>
</Gantt>
@code {
    private DateOnly selectedDate = DateOnly.FromDateTime( DateTime.Today );

    private List<TaskItem> tasks = CreateTasks();

    private static List<TaskItem> CreateTasks()
    {
        var baseDate = DateTime.Today.AddDays( -2 );

        var result = new List<TaskItem>
        {
            new() { Id = "1", Title = "Website redesign", Start = baseDate, End = baseDate.AddDays( 16 ) },
            new() { Id = "2", ParentId = "1", Title = "Discovery", Start = baseDate, End = baseDate.AddDays( 4 ) },
            new() { Id = "3", ParentId = "1", Title = "Implementation", Start = baseDate.AddDays( 4 ), End = baseDate.AddDays( 14 ) },
            new() { Id = "4", ParentId = "3", Title = "Components", Start = baseDate.AddDays( 5 ), End = baseDate.AddDays( 10 ) },
            new() { Id = "5", ParentId = "3", Title = "Accessibility pass", Start = baseDate.AddDays( 10 ), End = baseDate.AddDays( 13 ) },
            new() { Id = "6", ParentId = "1", Title = "Launch", Start = baseDate.AddDays( 14 ), End = baseDate.AddDays( 16 ) },
        };

        foreach ( var item in result )
        {
            item.Duration = Math.Max( 1, (int)Math.Ceiling( ( item.End - item.Start ).TotalDays ) );
        }

        return result;
    }

    public class TaskItem
    {
        public string Id { get; set; }

        public string ParentId { get; set; }

        public string Title { get; set; }

        public DateTime Start { get; set; }

        public DateTime End { get; set; }

        public int Duration { get; set; }
    }
}

Hierarchical Data Binding

Bind directly to nested task collections with ItemsField for tree-shaped data models.
Apr 27 - May 03, 2026
WBS
Task
Start
1
Mobile app release
Apr 28, 2026
1.1
Planning
Apr 28, 2026
1.2
Execution
May 02, 2026
1.2.1
API integration
May 03, 2026
1.2.2
QA
May 09, 2026
1.3
Go-live
May 14, 2026
Mon 27
Tue 28
Wed 29
Thu 30
Fri 01
Sat 02
Sun 03
Mobile app release
Planning
Execution
API integration
<Gantt TItem="TaskItem"
       Data="@tasks"
       Date="@selectedDate"
       SelectedView="GanttView.Week"
       ItemsField="Children"
       HierarchicalData
       DurationField="Duration">
    <GanttColumns>
        <GanttColumn Field="Wbs" Width="Width.Px(76)" TextAlignment="TextAlignment.Center" Visible="false" />
        <GanttColumn Field="Title" Title="Task" Expandable Width="Width.Px(220)" />
        <GanttColumn Field="Start" Width="Width.Px(130)" />
        <GanttColumn Field="End" Width="Width.Px(130)" Visible="false" />
        <GanttColumn Field="Duration" Width="Width.Px(90)" TextAlignment="TextAlignment.Center" Visible="false" />
    </GanttColumns>
    <GanttToolbar />
    <GanttViews>
        <GanttWeekView TimelineCellWidth="90" RowHeight="44" />
    </GanttViews>
</Gantt>
@code {
    private DateOnly selectedDate = DateOnly.FromDateTime( DateTime.Today );

    private List<TaskItem> tasks = CreateTasks();

    private static List<TaskItem> CreateTasks()
    {
        var baseDate = DateTime.Today.AddDays( -2 );

        var result = new List<TaskItem>
        {
            new()
            {
                Id = "1",
                Title = "Mobile app release",
                Start = baseDate,
                End = baseDate.AddDays( 18 ),
                Children = new()
                {
                    new()
                    {
                        Id = "2",
                        Title = "Planning",
                        Start = baseDate,
                        End = baseDate.AddDays( 4 ),
                    },
                    new()
                    {
                        Id = "3",
                        Title = "Execution",
                        Start = baseDate.AddDays( 4 ),
                        End = baseDate.AddDays( 16 ),
                        Children = new()
                        {
                            new()
                            {
                                Id = "4",
                                Title = "API integration",
                                Start = baseDate.AddDays( 5 ),
                                End = baseDate.AddDays( 11 ),
                            },
                            new()
                            {
                                Id = "5",
                                Title = "QA",
                                Start = baseDate.AddDays( 11 ),
                                End = baseDate.AddDays( 16 ),
                            },
                        },
                    },
                    new()
                    {
                        Id = "6",
                        Title = "Go-live",
                        Start = baseDate.AddDays( 16 ),
                        End = baseDate.AddDays( 18 ),
                    },
                },
            },
        };

        UpdateDuration( result );

        return result;
    }

    private static void UpdateDuration( IEnumerable<TaskItem> items )
    {
        foreach ( var item in items )
        {
            item.Duration = Math.Max( 1, (int)Math.Ceiling( ( item.End - item.Start ).TotalDays ) );
            UpdateDuration( item.Children );
        }
    }

    public class TaskItem
    {
        public string Id { get; set; }

        public string Title { get; set; }

        public DateTime Start { get; set; }

        public DateTime End { get; set; }

        public int Duration { get; set; }

        public List<TaskItem> Children { get; set; } = new();
    }
}

Built-in Editing

Enable Editable to use built-in create, add-child, update, and delete workflows. This example also demonstrates command-level control through CommandAllowed.
Apr 27 - May 03, 2026
Task
Start
Marketing campaign
Apr 28, 2026
Research
Apr 28, 2026
Creative
May 02, 2026
Distribution
May 07, 2026
Mon 27
Tue 28
Wed 29
Thu 30
Fri 01
Sat 02
Sun 03
Marketing campaign45%
Research100%
Creative70%
<Gantt TItem="TaskItem"
       Data="@tasks"
       Date="@selectedDate"
       SelectedView="GanttView.Week"
       DurationField="Duration"
       Editable
       CommandAllowed="@AllowCommand">
    <GanttColumns>
        <GanttColumn Field="Title" Title="Task" Expandable Width="Width.Px(230)" />
        <GanttColumn Field="Start" Width="Width.Px(130)" />
        <GanttColumn Field="End" Width="Width.Px(130)" Visible="false" />
        <GanttColumn Field="Duration" Width="Width.Px(90)" TextAlignment="TextAlignment.Center" Visible="false" />
        <GanttColumn Field="Progress" Width="Width.Px(96)" TextAlignment="TextAlignment.Center" Visible="false" />
        <GanttCommandColumn Width="Width.Px(60)" />
    </GanttColumns>
    <GanttToolbar />
    <GanttViews>
        <GanttWeekView TimelineCellWidth="90" RowHeight="44" />
    </GanttViews>
</Gantt>
@code {
    private DateOnly selectedDate = DateOnly.FromDateTime( DateTime.Today );

    private List<TaskItem> tasks = CreateTasks();

    private static List<TaskItem> CreateTasks()
    {
        var baseDate = DateTime.Today.AddDays( -2 );

        var result = new List<TaskItem>
        {
            new() { Id = "1", Title = "Marketing campaign", Start = baseDate, End = baseDate.AddDays( 15 ), Progress = 45d },
            new() { Id = "2", ParentId = "1", Title = "Research", Start = baseDate, End = baseDate.AddDays( 4 ), Progress = 100d },
            new() { Id = "3", ParentId = "1", Title = "Creative", Start = baseDate.AddDays( 4 ), End = baseDate.AddDays( 9 ), Progress = 70d },
            new() { Id = "4", ParentId = "1", Title = "Distribution", Start = baseDate.AddDays( 9 ), End = baseDate.AddDays( 15 ), Progress = 20d },
        };

        foreach ( var item in result )
        {
            item.Duration = Math.Max( 1, (int)Math.Ceiling( ( item.End - item.Start ).TotalDays ) );
        }

        return result;
    }

    private bool AllowCommand( GanttCommandContext<TaskItem> context )
    {
        if ( context.CommandType == GanttCommandType.Delete && context.Item?.ParentId is null )
            return false;

        return true;
    }

    public class TaskItem
    {
        public string Id { get; set; }

        public string ParentId { get; set; }

        public string Title { get; set; }

        public DateTime Start { get; set; }

        public DateTime End { get; set; }

        public int Duration { get; set; }

        public double Progress { get; set; }
    }
}

External Editing

By setting the UseInternalEditing=false Gantt raises command callbacks with the relevant item and context, but leaves the editing UI and persistence flow to your implementation. This is ideal for keeping Gantt as a pure view component while owning the user experience and data flow of your app.
Task
Start
Website redesign
Apr 28, 2026
Discovery
Apr 28, 2026
Implementation
May 02, 2026
Launch
May 10, 2026
Mon 27
Tue 28
Wed 29
Thu 30
Fri 01
Sat 02
Sun 03
Website redesign
Discovery
Implementation

Last external action: None

<Gantt TItem="TaskItem"
       Data="@tasks"
       Date="@selectedDate"
       SelectedView="GanttView.Week"
       DurationField="Duration"
       Editable
       UseInternalEditing="false"
       NewItemClicked="@OnNewItemClicked"
       AddChildItemClicked="@OnAddChildItemClicked"
       EditItemClicked="@OnEditItemClicked"
       DeleteItemClicked="@OnDeleteItemClicked">
    <GanttColumns>
        <GanttColumn Field="Title" Title="Task" Expandable Width="Width.Px( 230 )" />
        <GanttColumn Field="Start" Width="Width.Px( 130 )" />
        <GanttColumn Field="End" Width="Width.Px( 130 )" Visible="false" />
        <GanttColumn Field="Duration" Width="Width.Px( 90 )" TextAlignment="TextAlignment.Center" Visible="false" />
        <GanttCommandColumn Width="Width.Px( 176 )">
            <HeaderTemplate>
                @if ( context.CanAddTask )
                {
                    <Button Size="Size.ExtraSmall" Color="Color.Success" Outline Clicked="@context.AddTask">New</Button>
                }
            </HeaderTemplate>
            <DisplayTemplate>
                @if ( context.CanAddChild )
                {
                    <Button Size="Size.ExtraSmall" Color="Color.Secondary" Outline Margin="Margin.Is1.FromEnd" Clicked="@context.AddChild">Child</Button>
                }
                @if ( context.CanEdit )
                {
                    <Button Size="Size.ExtraSmall" Color="Color.Primary" Outline Margin="Margin.Is1.FromEnd" Clicked="@context.Edit">Edit</Button>
                }
                @if ( context.CanDelete )
                {
                    <Button Size="Size.ExtraSmall" Color="Color.Danger" Outline Clicked="@context.Delete">Delete</Button>
                }
            </DisplayTemplate>
        </GanttCommandColumn>
    </GanttColumns>
    <GanttViews>
        <GanttWeekView TimelineCellWidth="90" RowHeight="44" />
    </GanttViews>
</Gantt>

<Paragraph TextColor="TextColor.Muted" Margin="Margin.Is3.FromTop">
    Last external action: @lastAction
</Paragraph>

<Modal @bind-Visible="@editorVisible" Centered>
    <ModalContent>
        <ModalHeader>
            <ModalTitle>@editorModeTitle</ModalTitle>
            <CloseButton Clicked="@CloseEditor" />
        </ModalHeader>
        <ModalBody>
            <Paragraph TextColor="TextColor.Muted">
                This modal is owned by the page. Gantt only raises the command callbacks.
            </Paragraph>
            <Field>
                <FieldLabel>Title</FieldLabel>
                <FieldBody>
                    <TextInput @bind-Value="@editorTitle" Immediate="false" Placeholder="Task title" />
                </FieldBody>
            </Field>
        </ModalBody>
        <ModalFooter>
            <Button Color="Color.Secondary" Clicked="@CloseEditor">Cancel</Button>
            <Button Color="Color.Primary" Clicked="@SaveEditor">Save</Button>
        </ModalFooter>
    </ModalContent>
</Modal>
@code {
    private DateOnly selectedDate = DateOnly.FromDateTime( DateTime.Today );
    private List<TaskItem> tasks = CreateTasks();
    private bool editorVisible;
    private string editorModeTitle = "Edit task";
    private string editorTitle;
    private string editorParentId;
    private string editorTargetId;
    private TaskItem editorDraft;
    private string lastAction = "None";
    private int nextId = 100;

    private Task OnNewItemClicked( GanttCommandContext<TaskItem> context )
        => OpenEditor( context.Item, null, null, "Create task" );

    private Task OnAddChildItemClicked( GanttCommandContext<TaskItem> context )
        => OpenEditor( context.Item, context.ParentItem, null, $"Create child for {context.ParentItem?.Title}" );

    private Task OnEditItemClicked( GanttItemClickedEventArgs<TaskItem> context )
        => OpenEditor( context.Item, null, context.Item?.Id, $"Edit {context.Item?.Title}" );

    private Task OnDeleteItemClicked( GanttItemClickedEventArgs<TaskItem> context )
    {
        if ( context?.Item?.Id is null )
            return Task.CompletedTask;

        RemoveTaskWithChildren( tasks, context.Item.Id );
        lastAction = $"Deleted {context.Item.Title}";

        return Task.CompletedTask;
    }

    private Task OpenEditor( TaskItem item, TaskItem parentItem, string targetId, string modeTitle )
    {
        editorDraft = item?.Clone() ?? new TaskItem();
        editorParentId = parentItem?.Id;
        editorTargetId = targetId;
        editorTitle = editorDraft.Title ?? string.Empty;
        editorModeTitle = modeTitle;
        editorVisible = true;

        return Task.CompletedTask;
    }

    private Task CloseEditor()
    {
        editorVisible = false;
        editorDraft = null;
        editorParentId = null;
        editorTargetId = null;
        editorTitle = string.Empty;

        return Task.CompletedTask;
    }

    private Task SaveEditor()
    {
        if ( editorDraft is null )
            return Task.CompletedTask;

        editorDraft.Title = string.IsNullOrWhiteSpace( editorTitle )
            ? "Untitled task"
            : editorTitle.Trim();

        if ( string.IsNullOrEmpty( editorTargetId ) )
        {
            editorDraft.Id ??= $"task-{nextId++}";
            editorDraft.ParentId = editorParentId;
            tasks.Add( editorDraft.Clone() );
            lastAction = editorParentId is null
                ? $"Created {editorDraft.Title}"
                : $"Created child {editorDraft.Title}";
        }
        else
        {
            var existingTask = tasks.FirstOrDefault( x => x.Id == editorTargetId );

            if ( existingTask is not null )
            {
                existingTask.Title = editorDraft.Title;
                lastAction = $"Updated {existingTask.Title}";
            }
        }

        return CloseEditor();
    }

    private static void RemoveTaskWithChildren( List<TaskItem> list, string itemId )
    {
        var idsToDelete = new HashSet<string>( StringComparer.Ordinal ) { itemId };
        var changed = true;

        while ( changed )
        {
            changed = false;

            foreach ( var task in list )
            {
                if ( task.ParentId is not null && idsToDelete.Contains( task.ParentId ) && idsToDelete.Add( task.Id ) )
                    changed = true;
            }
        }

        list.RemoveAll( x => idsToDelete.Contains( x.Id ) );
    }

    private static List<TaskItem> CreateTasks()
    {
        var baseDate = DateTime.Today.AddDays( -2 );

        return new List<TaskItem>
        {
            new() { Id = "1", Title = "Website redesign", Start = baseDate, End = baseDate.AddDays( 14 ), Duration = 14 },
            new() { Id = "2", ParentId = "1", Title = "Discovery", Start = baseDate, End = baseDate.AddDays( 4 ), Duration = 4 },
            new() { Id = "3", ParentId = "1", Title = "Implementation", Start = baseDate.AddDays( 4 ), End = baseDate.AddDays( 12 ), Duration = 8 },
            new() { Id = "4", ParentId = "1", Title = "Launch", Start = baseDate.AddDays( 12 ), End = baseDate.AddDays( 14 ), Duration = 2 },
        };
    }

    public class TaskItem
    {
        public string Id { get; set; }

        public string ParentId { get; set; }

        public string Title { get; set; }

        public DateTime Start { get; set; }

        public DateTime End { get; set; }

        public int Duration { get; set; }

        public TaskItem Clone()
        {
            return new TaskItem
            {
                Id = Id,
                ParentId = ParentId,
                Title = Title,
                Start = Start,
                End = End,
                Duration = Duration,
            };
        }
    }
}

Multiple Views

Configure all timeline views in one Gantt instance, customize leading and trailing slots per view, and override week start day when needed.
Apr 27 - May 03, 2026
Task
Start
Project launch
Apr 28, 2026
Planning
Apr 28, 2026
Execution
May 02, 2026
Backend
May 03, 2026
Frontend
May 06, 2026
Go-live
May 14, 2026
Fri 24
Sat 25
Sun 26
Mon 27
Tue 28
Wed 29
Thu 30
Fri 01
Sat 02
Sun 03
Mon 04
Tue 05
Wed 06
Project launch
Planning
Execution
Backend
Frontend

Current date: 4/30/2026 | View: Week

<Gantt TItem="TaskItem"
       Data="@tasks"
       @bind-Date="@selectedDate"
       @bind-SelectedView="@selectedView"
       FirstDayOfWeek="DayOfWeek.Sunday"
       DurationField="Duration">
    <GanttColumns>
        <GanttColumn Field="Title" Title="Task" Expandable Width="Width.Px(220)" />
        <GanttColumn Field="Start" Width="Width.Px(130)" />
        <GanttColumn Field="End" Width="Width.Px(130)" Visible="false" />
        <GanttColumn Field="Duration" Width="Width.Px(90)" TextAlignment="TextAlignment.Center" Visible="false" />
    </GanttColumns>
    <GanttToolbar />
    <GanttViews>
        <GanttDayView TimelineCellWidth="56" RowHeight="44" LeadingSlots="2" TrailingSlots="2" />
        <GanttWeekView TimelineCellWidth="92" RowHeight="44" LeadingSlots="3" TrailingSlots="3" FirstDayOfWeek="DayOfWeek.Monday" />
        <GanttMonthView TimelineCellWidth="38" RowHeight="44" LeadingSlots="5" TrailingSlots="5" />
        <GanttYearView TimelineCellWidth="80" RowHeight="44" LeadingSlots="1" TrailingSlots="1" />
    </GanttViews>
</Gantt>

<Paragraph TextColor="TextColor.Muted" Margin="Margin.Is2.FromTop">
    Current date: @selectedDate | View: @selectedView
</Paragraph>
@code {
    private DateOnly selectedDate = DateOnly.FromDateTime( DateTime.Today );

    private GanttView selectedView = GanttView.Week;

    private List<TaskItem> tasks = CreateTasks();

    private static List<TaskItem> CreateTasks()
    {
        var baseDate = DateTime.Today.AddDays( -2 );

        var result = new List<TaskItem>
        {
            new() { Id = "1", Title = "Project launch", Start = baseDate, End = baseDate.AddDays( 18 ) },
            new() { Id = "2", ParentId = "1", Title = "Planning", Start = baseDate, End = baseDate.AddDays( 4 ) },
            new() { Id = "3", ParentId = "1", Title = "Execution", Start = baseDate.AddDays( 4 ), End = baseDate.AddDays( 16 ) },
            new() { Id = "4", ParentId = "3", Title = "Backend", Start = baseDate.AddDays( 5 ), End = baseDate.AddDays( 11 ) },
            new() { Id = "5", ParentId = "3", Title = "Frontend", Start = baseDate.AddDays( 8 ), End = baseDate.AddDays( 15 ) },
            new() { Id = "6", ParentId = "1", Title = "Go-live", Start = baseDate.AddDays( 16 ), End = baseDate.AddDays( 18 ) },
        };

        foreach ( var item in result )
        {
            item.Duration = Math.Max( 1, (int)Math.Ceiling( ( item.End - item.Start ).TotalDays ) );
        }

        return result;
    }

    public class TaskItem
    {
        public string Id { get; set; }

        public string ParentId { get; set; }

        public string Title { get; set; }

        public DateTime Start { get; set; }

        public DateTime End { get; set; }

        public int Duration { get; set; }
    }
}

Auto Expand View

Enable AutoExpandView when the visible range should follow the loaded task dates instead of the bound Date. This sample keeps the anchor date intentionally outside the task range, so switching the toggle off shows the default date-based range again.
Mar 27 - May 08, 2026
Task
Start
Auto-expand release
Mar 28, 2026
Design phase
Mar 28, 2026
Implementation
Apr 04, 2026
Backend services
Apr 06, 2026
Frontend polish
Apr 13, 2026
Validation and rollout
Apr 27, 2026
March 2026
April 2026
May 2026
Fri 27
Sat 28
Sun 29
Mon 30
Tue 31
Wed 01
Thu 02
Fri 03
Sat 04
Sun 05
Mon 06
Tue 07
Wed 08
Thu 09
Fri 10
Sat 11
Sun 12
Mon 13
Tue 14
Wed 15
Thu 16
Fri 17
Sat 18
Sun 19
Mon 20
Tue 21
Wed 22
Thu 23
Fri 24
Sat 25
Sun 26
Mon 27
Tue 28
Wed 29
Thu 30
Fri 01
Sat 02
Sun 03
Mon 04
Tue 05
Wed 06
Thu 07
Fri 08
Auto-expand release
Design phase
Implementation
Backend services
Frontend polish
Validation and rollout

Anchor date: 1/30/2026 | View: Week | AutoExpandView: True

<Field Margin="Margin.Is3.FromBottom">
    <Switch @bind-Value="@autoExpandView">Auto expand current view to the loaded task range</Switch>
</Field>

<Gantt TItem="TaskItem"
       Data="@tasks"
       @bind-Date="@selectedDate"
       @bind-SelectedView="@selectedView"
       AutoExpandView="@autoExpandView"
       DurationField="Duration">
    <GanttColumns>
        <GanttColumn Field="Title" Title="Task" Expandable Width="Width.Px( 220 )" />
        <GanttColumn Field="Start" Width="Width.Px( 130 )" />
        <GanttColumn Field="End" Width="Width.Px( 130 )" Visible="false" />
        <GanttColumn Field="Duration" Width="Width.Px( 90 )" TextAlignment="TextAlignment.Center" Visible="false" />
    </GanttColumns>
    <GanttToolbar />
    <GanttViews>
        <GanttWeekView TimelineCellWidth="92" RowHeight="44" />
        <GanttMonthView TimelineCellWidth="38" RowHeight="44" />
        <GanttYearView TimelineCellWidth="84" RowHeight="44" />
    </GanttViews>
</Gantt>

<Paragraph TextColor="TextColor.Muted" Margin="Margin.Is2.FromTop">
    Anchor date: @selectedDate | View: @selectedView | AutoExpandView: @autoExpandView
</Paragraph>
@code {
    private bool autoExpandView = true;

    private DateOnly selectedDate = DateOnly.FromDateTime( DateTime.Today.AddMonths( -3 ) );

    private GanttView selectedView = GanttView.Week;

    private List<TaskItem> tasks = CreateTasks();

    private static List<TaskItem> CreateTasks()
    {
        DateTime rangeStart = new DateTime( DateTime.Today.Year, DateTime.Today.Month, 1 ).AddDays( -4 );

        List<TaskItem> result = new()
        {
            new() { Id = "1", Title = "Auto-expand release", Start = rangeStart, End = rangeStart.AddDays( 41 ) },
            new() { Id = "2", ParentId = "1", Title = "Design phase", Start = rangeStart, End = rangeStart.AddDays( 8 ) },
            new() { Id = "3", ParentId = "1", Title = "Implementation", Start = rangeStart.AddDays( 7 ), End = rangeStart.AddDays( 28 ) },
            new() { Id = "4", ParentId = "3", Title = "Backend services", Start = rangeStart.AddDays( 9 ), End = rangeStart.AddDays( 18 ) },
            new() { Id = "5", ParentId = "3", Title = "Frontend polish", Start = rangeStart.AddDays( 16 ), End = rangeStart.AddDays( 31 ) },
            new() { Id = "6", ParentId = "1", Title = "Validation and rollout", Start = rangeStart.AddDays( 30 ), End = rangeStart.AddDays( 41 ) },
        };

        foreach ( TaskItem item in result )
        {
            item.Duration = Math.Max( 1, (int)Math.Ceiling( ( item.End - item.Start ).TotalDays ) );
        }

        return result;
    }

    public class TaskItem
    {
        public string Id { get; set; }

        public string ParentId { get; set; }

        public string Title { get; set; }

        public DateTime Start { get; set; }

        public DateTime End { get; set; }

        public int Duration { get; set; }
    }
}

Template Customization

Customize multiple Gantt surfaces with templates, including header cells, tree cells, command cells, timeline headers, and task bars.
Apr 27 - May 03, 2026
Task
Duration
Platform update
13d
Core services
7d
Web client
7d
Release prep
2d
Mon 27
Tue 28
Wed 29
Thu 30
Fri 01
Sat 02
Sun 03
Platform update
Core services
Web client
<Gantt TItem="TaskItem"
       Data="@tasks"
       Date="@selectedDate"
       SelectedView="GanttView.Week"
       DurationField="Duration"
       Editable>
    <ChildContent>
        <GanttColumns>
            <GanttColumn Field="Title" Title="Task" Expandable Width="Width.Px(230)">
                <HeaderTemplate>
                    <Icon Name="IconName.List" Margin="Margin.Is1.FromEnd" />
                    <Span>@context.Text</Span>
                </HeaderTemplate>
            </GanttColumn>
            <GanttColumn Field="Duration" Width="Width.Px(90)" TextAlignment="TextAlignment.Center">
                <DisplayTemplate>
                    <Badge Color="Color.Info" Pill>@($"{context.Value}d")</Badge>
                </DisplayTemplate>
            </GanttColumn>
            <GanttCommandColumn Width="Width.Px(176)">
                <DisplayTemplate>
                    @if ( context.CanAddChild )
                    {
                        <Button Size="Size.ExtraSmall" Color="Color.Secondary" Outline Margin="Margin.Is1.FromEnd" Clicked="@context.AddChild">Child</Button>
                    }
                    @if ( context.CanEdit )
                    {
                        <Button Size="Size.ExtraSmall" Color="Color.Primary" Outline Margin="Margin.Is1.FromEnd" Clicked="@context.Edit">Edit</Button>
                    }
                    @if ( context.CanDelete )
                    {
                        <Button Size="Size.ExtraSmall" Color="Color.Danger" Outline Clicked="@context.Delete">Delete</Button>
                    }
                </DisplayTemplate>
            </GanttCommandColumn>
        </GanttColumns>

        <GanttToolbar />

        <GanttViews>
            <GanttWeekView TimelineCellWidth="92" RowHeight="44" />
        </GanttViews>
    </ChildContent>

    <TimelineHeaderCellTemplate>
        <Span TextSize="TextSize.Small" TextWeight="TextWeight.SemiBold">
            @context.Start.ToString( "ddd dd" )
        </Span>
    </TimelineHeaderCellTemplate>

    <TaskItemTemplate>
        <Span TextWeight="TextWeight.SemiBold">@context.Item.Title</Span>
    </TaskItemTemplate>
</Gantt>
@code {
    private DateOnly selectedDate = DateOnly.FromDateTime( DateTime.Today );

    private List<TaskItem> tasks = CreateTasks();

    private static List<TaskItem> CreateTasks()
    {
        var baseDate = DateTime.Today.AddDays( -2 );

        var result = new List<TaskItem>
        {
            new() { Id = "1", Title = "Platform update", Start = baseDate, End = baseDate.AddDays( 13 ) },
            new() { Id = "2", ParentId = "1", Title = "Core services", Start = baseDate, End = baseDate.AddDays( 7 ) },
            new() { Id = "3", ParentId = "1", Title = "Web client", Start = baseDate.AddDays( 4 ), End = baseDate.AddDays( 11 ) },
            new() { Id = "4", ParentId = "1", Title = "Release prep", Start = baseDate.AddDays( 11 ), End = baseDate.AddDays( 13 ) },
        };

        foreach ( var item in result )
        {
            item.Duration = Math.Max( 1, (int)Math.Ceiling( ( item.End - item.Start ).TotalDays ) );
        }

        return result;
    }

    public class TaskItem
    {
        public string Id { get; set; }

        public string ParentId { get; set; }

        public string Title { get; set; }

        public DateTime Start { get; set; }

        public DateTime End { get; set; }

        public int Duration { get; set; }
    }
}

API

Parameters

Gantt

Parameter Description TypeDefault
ActionColumnWidth

Specifies action column width in pixels.

double42d
AddChildCommandAllowed

Determines whether creating child items is allowed.

booltrue
AutoExpandView

Determines whether the active view range automatically expands to include all items.

boolfalse
ChildContent

Defines child content used to declare toolbar and views.

RenderFragmentnull
Data

Specifies the data source displayed by the Gantt chart.

IEnumerable<TItem>null
Date

Specifies the anchor date used by the selected view.

DateOnlyDateOnly.FromDateTime( DateTime.Today )
DateColumnWidth

Specifies fallback date column width in pixels used when an auto-sized value cannot be calculated.

double140d
DeleteCommandAllowed

Determines whether deleting existing items is allowed.

booltrue
DescriptionField

Specifies the data field used for item descriptions.

string"Description"
Draggable

Determines whether timeline item bars can be dragged to move their start and end dates together.

booltrue
DurationField

Specifies the data field used for item duration, in days.

string"Duration"
Editable

Determines whether item editing is enabled.

boolfalse
EditCommandAllowed

Determines whether editing existing items is allowed.

booltrue
EndField

Specifies the data field used for item end dates.

string"End"
FirstDayOfWeek

Specifies the first day of the week used for date calculations.

DayOfWeekDayOfWeek.Monday
HeaderRowHeight

Specifies header row height in pixels.

doubleDefaultHeaderRowHeight
HierarchicalData

Determines whether hierarchical data mode is forced when both parent-id and items mapping exist.

boolfalse
IdField

Specifies the data field that contains each item's unique identifier.

string"Id"
ItemsField

Specifies the data field that contains child items for hierarchical data.

string"Items"
KeyboardNavigation

Determines whether basic keyboard navigation is enabled for tree rows.

booltrue
Localizers

Provides custom localizers for Gantt UI text.

GanttLocalizersnull
MinBarWidth

Specifies minimum item bar width in pixels.

double14d
NewCommandAllowed

Determines whether creating new top-level items is allowed.

booltrue
ParentIdField

Specifies the data field that contains each item's parent identifier.

string"ParentId"
ProgressField

Specifies the data field used for item progress values.

string"Progress"
Resizable

Determines whether timeline item bars can be resized by dragging their start and end edges.

booltrue
SearchInputWidth

Specifies search input width in pixels.

doubleDefaultSearchInputWidth
SearchText

Specifies the search text used to filter tree rows.

string
SelectedRow

Specifies the currently selected tree row item.

TItemnull
SelectedView

Specifies the active Gantt view.

Possible values:Day, Week, Month, Year

GanttViewGanttView.Week
ShowToggleAllCommands

Determines whether toggle-all commands (expand/collapse all) are visible in the toolbar.

booltrue
ShowToolbar

Determines whether toolbar is rendered.

booltrue
Sortable

Determines whether tree column sorting is enabled.

booltrue
StartField

Specifies the data field used for item start dates.

string"Start"
TaskItemTemplate

Defines template used to render timeline task content.

RenderFragment<GanttItemContext<TItem>>null
TimelineHeaderCellTemplate

Defines template used to render timeline header cells.

RenderFragment<GanttTimelineHeaderCellContext>null
TitleColumnWidth

Specifies title column width in pixels.

double320d
TitleField

Specifies the data field used for item titles.

string"Title"
TreeCommandCellTemplate

Defines template used to render command cell content.

RenderFragment<GanttTreeCommandCellContext<TItem>>null
TreeCommandHeaderTemplate

Defines template used to render command header content.

RenderFragment<GanttTreeCommandHeaderContext<TItem>>null
TreeIndentSize

Specifies tree indentation size per level in pixels.

double18d
TreeToggleWidth

Specifies tree toggle placeholder width in pixels.

doubleDefaultTreeToggleWidth
UseInternalEditing

Determines whether built-in modal editing and internal data mutation are used.

booltrue

GanttColumn

Parameter Description TypeDefault
CellsEditableOnEditCommand

Determines whether this column is editable during edit-item command.

booltrue
CellsEditableOnNewCommand

Determines whether this column is editable during new-item command.

booltrue
Displayable

Determines whether column can be shown in column picker.

booltrue
DisplayFormat

Specifies display format for default display text.

string
DisplayFormatProvider

Specifies display format provider.

IFormatProvidernull
DisplayTemplate

Defines custom display template.

RenderFragment<GanttColumnDisplayContext<TItem>>null
Editable

Determines whether this column is editable in edit forms.

booltrue
EditTemplate

Defines custom edit template.

RenderFragment<GanttColumnEditContext<TItem>>null
Expandable

Determines whether this column should render tree expander.

boolfalse
Field

Field name bound to this column.

string
HeaderTemplate

Defines custom header template.

RenderFragment<GanttColumnHeaderContext<TItem>>null
Sortable

Determines whether this column can be sorted.

booltrue
SortField

Specifies field used by sort operation. Defaults to Field.

string
TextAlignment

Specifies text alignment for header and cell.

Possible values:Default, Start, End, Center, Justified

TextAlignmentDefault
Title

Optional title shown in header.

string
Visible

Determines whether column is currently visible.

booltrue
Width

Specifies width.

IFluentSizingnull

GanttCommandColumn

Parameter Description TypeDefault
Displayable

Determines whether column can be shown in column picker.

booltrue
DisplayFormat

Specifies display format for default display text.

string
DisplayFormatProvider

Specifies display format provider.

IFormatProvidernull
DisplayTemplate

Defines custom command display template.

RenderFragment<GanttCommandColumnDisplayContext<TItem>>null
EditTemplate

Defines custom edit template.

RenderFragment<GanttColumnEditContext<TItem>>null
Expandable

Determines whether this column should render tree expander.

boolfalse
Field

Field name bound to this column.

string
HeaderTemplate

Defines custom header template.

RenderFragment<GanttColumnHeaderContext<TItem>>null
Sortable

Determines whether this column can be sorted.

booltrue
SortField

Specifies field used by sort operation. Defaults to Field.

string
TextAlignment

Specifies text alignment for header and cell.

Possible values:Default, Start, End, Center, Justified

TextAlignmentDefault
Title

Optional title shown in header.

string
Visible

Determines whether column is currently visible.

booltrue
Width

Specifies width.

IFluentSizingnull

GanttDayView

Parameter Description TypeDefault
ItemTemplate

Template for rendering the timeline item bar.

RenderFragment<GanttItemContext<TItem>>null
LeadingSlots

Number of extra slots shown before the anchor period.

int0
RowHeight

Height of each timeline row in pixels.

double44
RowTemplate

Template for rendering the row cell.

RenderFragment<GanttRowContext<TItem>>null
TimelineCellWidth

Width of each timeline cell in pixels.

double72
TrailingSlots

Number of extra slots shown after the anchor period.

int0

GanttWeekView

Parameter Description TypeDefault
FirstDayOfWeek

Specifies the first day of the week used for date calculations.

DayOfWeek?null
ItemTemplate

Template for rendering the timeline item bar.

RenderFragment<GanttItemContext<TItem>>null
LeadingSlots

Number of extra slots shown before the anchor period.

int0
RowHeight

Height of each timeline row in pixels.

double44
RowTemplate

Template for rendering the row cell.

RenderFragment<GanttRowContext<TItem>>null
TimelineCellWidth

Width of each timeline cell in pixels.

double72
TrailingSlots

Number of extra slots shown after the anchor period.

int0

GanttMonthView

Parameter Description TypeDefault
ItemTemplate

Template for rendering the timeline item bar.

RenderFragment<GanttItemContext<TItem>>null
LeadingSlots

Number of extra slots shown before the anchor period.

int0
RowHeight

Height of each timeline row in pixels.

double44
RowTemplate

Template for rendering the row cell.

RenderFragment<GanttRowContext<TItem>>null
TimelineCellWidth

Width of each timeline cell in pixels.

double72
TrailingSlots

Number of extra slots shown after the anchor period.

int0

GanttYearView

Parameter Description TypeDefault
ItemTemplate

Template for rendering the timeline item bar.

RenderFragment<GanttItemContext<TItem>>null
LeadingSlots

Number of extra slots shown before the anchor period.

int0
RowHeight

Height of each timeline row in pixels.

double44
RowTemplate

Template for rendering the row cell.

RenderFragment<GanttRowContext<TItem>>null
TimelineCellWidth

Width of each timeline cell in pixels.

double72
TrailingSlots

Number of extra slots shown after the anchor period.

int0

Events

Gantt

Event Description Type
AddChildItemClicked

Notifies when the add-child command is triggered.

EventCallback<GanttCommandContext<TItem>>
CommandAllowed

Provides a callback that determines whether a command is allowed for a given item.

Func<GanttCommandContext<TItem>, bool>
DateChanged

Notifies when Date changes.

EventCallback<DateOnly>
DeleteItemClicked

Notifies when the delete action is triggered for an item.

EventCallback<GanttItemClickedEventArgs<TItem>>
EditItemClicked

Notifies when the edit action is triggered for an item.

EventCallback<GanttItemClickedEventArgs<TItem>>
ItemClicked

Notifies when a timeline item is clicked.

EventCallback<GanttItemClickedEventArgs<TItem>>
ItemInserted

Notifies after a new item is inserted.

EventCallback<GanttInsertedItem<TItem>>
ItemInserting

Notifies before a new item is inserted.

EventCallback<GanttCancellableItemChange<TItem>>
ItemRemoved

Notifies after an item is removed.

EventCallback<GanttUpdatedItem<TItem>>
ItemRemoving

Notifies before an item is removed.

EventCallback<GanttCancellableItemChange<TItem>>
ItemStyling

Defines styling applied to timeline bars for each item.

Action<TItem, GanttItemStyling>
ItemUpdated

Notifies after an item is updated.

EventCallback<GanttUpdatedItem<TItem>>
ItemUpdating

Notifies before an existing item is updated.

EventCallback<GanttCancellableItemChange<TItem>>
NewIdCreator

Provides a factory used to create new item identifiers.

Func<object>
NewItemClicked

Notifies when the new-item command is triggered.

EventCallback<GanttCommandContext<TItem>>
NewItemCreator

Provides a factory used to create new item instances.

Func<TItem>
ReadData

Notifies when the Gantt requests data in manual read mode.

EventCallback<GanttReadDataEventArgs<TItem>>
SearchTextChanged

Notifies when SearchText changes.

EventCallback<string>
SelectedRowChanged

Notifies when SelectedRow changes.

EventCallback<TItem>
SelectedViewChanged

Notifies when SelectedView changes.

EventCallback<GanttView>

Methods

Gantt

Method DescriptionReturnParameters
AddChild Creates a new child item for specified parent. TaskTItem parentItem
CollapseAll Collapses all nodes in the tree, including all nested child nodes. Task
Delete Deletes specified item. TaskTItem item
Edit Puts chart in edit-item state for specified item. TaskTItem item
ExpandAll Expands all nodes in the tree, including all nested child nodes. Task
GetState Gets current Gantt state. Task<GanttState<TItem>>
LoadState Loads and applies Gantt state. TaskGanttState<TItem> ganttState
NavigateNextPeriod Navigates to the next period based on the selected view. Task
NavigatePreviousPeriod Navigates to the previous period based on the selected view. Task
NavigateToday Navigates the chart to current date. Task
New Creates a new item using configured new-item factory. Task
New Creates a new top-level item. TaskTItem item
New Puts chart in new-item editing state. TaskTItem item, TItem parentItem
NotifyBarDragMouseMove Receives JavaScript drag-move notifications for the active timeline item drag operation. Taskdouble clientX
NotifyBarDragMouseUp Receives JavaScript drag-end notifications for the active timeline item drag operation. Taskdouble clientX, bool dragged
ShowDayView Switches to Day view. Task
ShowMonthView Switches to Month view. Task
ShowWeekView Switches to Week view. Task
ShowYearView Switches to Year view. Task

GanttColumn

Method DescriptionReturnParameters
CellValueIsEditable Gets whether the column value is editable for current edit state. boolGanttEditState editState
CanSort Returns true when column can be sorted. bool
FormatDisplayValue Gets formatted display text for this column. stringobject value
GetSortField Gets field name to sort by. string
GetSortValue Gets raw value used for sorting. objectTItem item
GetValue Gets raw value for this column. objectTItem item

GanttCommandColumn

Method DescriptionReturnParameters
CanSort Returns true when column can be sorted. bool
FormatDisplayValue Gets formatted display text for this column. stringobject value
GetSortField Gets field name to sort by. string
GetSortValue Gets raw value used for sorting. objectTItem item
GetValue Gets raw value for this column. objectTItem item
On this page