﻿# Gantt: Drag & Resize

Drag task bars to move them and drag their edges to resize. Zero-duration tasks render as milestone diamonds.

Keywords: gantt, drag, resize, move, milestone, diamond, interactive

> API reference: [RadzenGantt API](https://blazor.radzen.com/docs/api/Radzen.Blazor.RadzenGantt-1.md)

## Examples

## Blazor Gantt Drag &amp; Resize

Drag task bars to move them and drag their edges to resize. Zero-duration tasks appear as milestone diamonds.

```razor
<RadzenGantt @ref="gantt" TItem="GanttTask"
             Data="@tasks"
             Dependencies="@dependencies"
             IdProperty="@nameof(GanttTask.Id)"
             ParentIdProperty="@nameof(GanttTask.ParentId)"
             TextProperty="@nameof(GanttTask.Name)"
             StartProperty="@nameof(GanttTask.Start)"
             EndProperty="@nameof(GanttTask.End)"
             ProgressProperty="@nameof(GanttTask.Progress)"
             TaskMove="@OnTaskMove"
             TaskResize="@OnTaskResize"
             AllowColumnResize="true"
             AllowColumnReorder="true"
             Style="width: 100%; height: 520px;">
    <Columns>
        <RadzenGanttColumn Title="Task" Property="@nameof(GanttTask.Name)" Frozen="true" Width="200px" />
        <RadzenGanttColumn Title="Start" Property="@nameof(GanttTask.Start)" Width="120px" FormatString="{0:d}" />
        <RadzenGanttColumn Title="End" Property="@nameof(GanttTask.End)" Width="120px" FormatString="{0:d}" />
        <RadzenGanttColumn Title="Progress" Property="@nameof(GanttTask.Progress)" Width="140px" FormatString="{0}" FormatProvider="@percentProvider" />
    </Columns>
</RadzenGantt>

<EventConsole @ref=@console Style="min-height: 160px;" class="rz-mt-4" />

@code {
    RadzenGantt<GanttTask> gantt;
    MyPercentProvider percentProvider = new();

    List<GanttTask> tasks = new();
    List<GanttDependency<GanttTask>> dependencies;
    EventConsole console;

    protected override void OnInitialized()
    {
        base.OnInitialized();

        tasks = new()
        {
            new() { Id = 1, Name = "Project", Start = DateTime.Today.AddDays(-2), End = DateTime.Today.AddDays(30), Progress = 35 },
            new() { Id = 2, ParentId = 1, Name = "Discovery", Start = DateTime.Today.AddDays(-2), End = DateTime.Today.AddDays(5), Progress = 100 },
            new() { Id = 3, ParentId = 1, Name = "Implementation", Start = DateTime.Today.AddDays(6), End = DateTime.Today.AddDays(24), Progress = 25 },
            new() { Id = 4, ParentId = 3, Name = "API", Start = DateTime.Today.AddDays(6), End = DateTime.Today.AddDays(14), Progress = 60 },
            new() { Id = 5, ParentId = 3, Name = "UI", Start = DateTime.Today.AddDays(10), End = DateTime.Today.AddDays(22), Progress = 10 },
            new() { Id = 6, ParentId = 1, Name = "QA + Release", Start = DateTime.Today.AddDays(25), End = DateTime.Today.AddDays(30), Progress = 0 },
            new() { Id = 7, ParentId = 2, Name = "Stakeholder interviews", Start = DateTime.Today.AddDays(-2), End = DateTime.Today.AddDays(1), Progress = 100 },
            new() { Id = 8, ParentId = 2, Name = "Requirements sign-off", Start = DateTime.Today.AddDays(4), End = DateTime.Today.AddDays(4), Progress = 100 },
            new() { Id = 9, ParentId = 3, Name = "Architecture", Start = DateTime.Today.AddDays(6), End = DateTime.Today.AddDays(9), Progress = 40 },
            new() { Id = 10, ParentId = 4, Name = "Auth endpoints", Start = DateTime.Today.AddDays(6), End = DateTime.Today.AddDays(9), Progress = 80 },
            new() { Id = 11, ParentId = 4, Name = "Data contracts", Start = DateTime.Today.AddDays(8), End = DateTime.Today.AddDays(12), Progress = 50 },
            new() { Id = 12, ParentId = 4, Name = "Caching", Start = DateTime.Today.AddDays(11), End = DateTime.Today.AddDays(14), Progress = 20 },
            new() { Id = 13, ParentId = 5, Name = "Layout", Start = DateTime.Today.AddDays(10), End = DateTime.Today.AddDays(13), Progress = 60 },
            new() { Id = 14, ParentId = 5, Name = "Components", Start = DateTime.Today.AddDays(12), End = DateTime.Today.AddDays(18), Progress = 15 },
            new() { Id = 15, ParentId = 5, Name = "Theme polish", Start = DateTime.Today.AddDays(18), End = DateTime.Today.AddDays(22), Progress = 0 },
            new() { Id = 16, ParentId = 3, Name = "Code freeze", Start = DateTime.Today.AddDays(24), End = DateTime.Today.AddDays(24), Progress = 0 },
            new() { Id = 17, ParentId = 6, Name = "Test plan", Start = DateTime.Today.AddDays(25), End = DateTime.Today.AddDays(26), Progress = 0 },
            new() { Id = 18, ParentId = 6, Name = "Regression", Start = DateTime.Today.AddDays(26), End = DateTime.Today.AddDays(29), Progress = 0 },
            new() { Id = 19, ParentId = 6, Name = "Go-live", Start = DateTime.Today.AddDays(30), End = DateTime.Today.AddDays(30), Progress = 0 },
        };

        dependencies = new()
        {
            new() { From = tasks[1], To = tasks[2] },
            new() { From = tasks[6], To = tasks[7] },
            new() { From = tasks[8], To = tasks[3] },
            new() { From = tasks[3], To = tasks[15] },
            new() { From = tasks[15], To = tasks[5] },
            new() { From = tasks[17], To = tasks[18] },
        };
    }

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await base.OnAfterRenderAsync(firstRender);

        if (firstRender)
        {
            await gantt.ExpandRows(tasks);
        }
    }

    void OnTaskMove(GanttTaskMovedEventArgs<GanttTask> args)
    {
        args.Data.Start = args.NewStart;
        args.Data.End = args.NewEnd;

        console.Log($"Moved \"{args.Data.Name}\" to {args.NewStart:d} \u2013 {args.NewEnd:d}");
    }

    void OnTaskResize(GanttTaskMovedEventArgs<GanttTask> args)
    {
        args.Data.Start = args.NewStart;
        args.Data.End = args.NewEnd;

        console.Log($"Resized \"{args.Data.Name}\" to {args.NewStart:d} \u2013 {args.NewEnd:d}");
    }

    public class MyPercentProvider : IFormatProvider, ICustomFormatter
    {
        public string Format(string format, object arg, IFormatProvider formatProvider)
        {
            return string.Format("{0:P0}", (double?)arg / 100);
        }

        public object GetFormat(Type formatType)
        {
            if (formatType == typeof(ICustomFormatter))
            {
                return this;
            }

            return null;
        }
    }
}
```
