Split Task Sement in SfGantt is not drawn for the exact date time..

I am working with a Blazor WebAssembly page using the Syncfusion Blazor SfGantt chart with the split tasks feature enabled. Each segment (split task) has its own start and end DateTime values. However, the segments are not being rendered according to their exact date and time within a task row.

For example, in Task 1, I defined the following segment:

segments.Add(new SegmentModel
{
Id = 1,
TaskID = 1,
SegmentStartDate = new DateTime(2026, 4, 6, 9, 20, 0),
SegmentEndDate = new DateTime(2026, 4, 7, 7, 30, 0)
});

Although the segment is supposed to start at April 6, 2026, 9:20 AM and end at April 7, 2026, 7:30 AM, it is instead rendered starting at 8:00 AM on April 6 and ending at 22:00 PM on the same day.

How can I ensure that each segment is rendered with its exact start and end DateTime values for each task row in the SfGantt chart?

 SfGantt1.jpg 

@page "/" @using Syncfusion.Blazor.Gantt @rendermode InteractiveWebAssembly <h3>Syncfusion SfGantt - Segmented Tasks (No Subtasks) • .NET 10 Blazor WebAssembly</h3> <p>Each task has 4–6 split segments. Timeline: Top tier = Day, Bottom tier = Hour. Project range = 15 days.</p> <SfGantt TValue="TaskData" DataSource="@taskCollection" Height="700px" Width="100%" ProjectStartDate="@projectStart" ProjectEndDate="@projectEnd" DurationUnit="DurationUnit.Hour" EnableRowVirtualization="false"> <GanttTaskFields Id="TaskID" Name="TaskName" StartDate="StartDate" EndDate="EndDate" Progress="Progress"> </GanttTaskFields> <!-- Correct segmented tasks binding (official way) --> <GanttSegmentFields TValue="TaskData" TSegments="SegmentModel" PrimaryKey="Id" ForeignKey="TaskID" StartDate="SegmentStartDate" EndDate="SegmentEndDate" DataSource="@segmentCollection"> </GanttSegmentFields> <!-- Timeline Settings --> <GanttTimelineSettings TimelineUnitSize="60"> <GanttTopTierSettings Unit="TimelineViewMode.Day" Format="ddd, MMM dd"></GanttTopTierSettings> <GanttBottomTierSettings Unit="TimelineViewMode.Hour" Format="HH:mm"></GanttBottomTierSettings> </GanttTimelineSettings> <GanttDayWorkingTimeCollection> <GanttDayWorkingTime From="0" To="24"></GanttDayWorkingTime> </GanttDayWorkingTimeCollection> <GanttColumns> <GanttColumn Field="TaskID" HeaderText="ID" Width="80" IsPrimaryKey="true"></GanttColumn> <GanttColumn Field="TaskName" HeaderText="Task Name" Width="280"></GanttColumn> <GanttColumn Field="StartDate" HeaderText="Overall Start" Width="170" Format="M/d/yyyy HH:mm"></GanttColumn> <GanttColumn Field="EndDate" HeaderText="Overall End" Width="170" Format="M/d/yyyy HH:mm"></GanttColumn> <GanttColumn Field="Progress" HeaderText="Progress (%)" Width="110"></GanttColumn> </GanttColumns> <GanttEditSettings AllowEditing="true" AllowAdding="true" AllowDeleting="true" AllowTaskbarEditing="true" Mode="Syncfusion.Blazor.Gantt.EditMode.Dialog"> </GanttEditSettings> </SfGantt> @code { private DateTime projectStart = new DateTime(2026, 4, 6, 0, 0, 0); private DateTime projectEnd = new DateTime(2026, 4, 21, 23, 59, 59); private List<TaskData> taskCollection = new(); private List<SegmentModel> segmentCollection = new(); protected override void OnInitialized() { taskCollection = GetTaskCollection(); segmentCollection = GetSegmentCollection(); } public class TaskData { public int TaskID { get; set; } public string TaskName { get; set; } = string.Empty; public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public int Progress { get; set; } } public class SegmentModel { public int Id { get; set; } public int TaskID { get; set; } public DateTime SegmentStartDate { get; set; } public DateTime SegmentEndDate { get; set; } } private List<TaskData> GetTaskCollection() { return new List<TaskData> { new TaskData { TaskID = 1, TaskName = "UI Wireframing", StartDate = new DateTime(2026, 4, 6, 8, 0, 0), EndDate = new DateTime(2026, 4, 14, 19, 0, 0), Progress = 75 }, new TaskData { TaskID = 2, TaskName = "Backend API Design", StartDate = new DateTime(2026, 4, 6, 13, 0, 0), EndDate = new DateTime(2026, 4, 15, 15, 0, 0), Progress = 60 }, new TaskData { TaskID = 3, TaskName = "Database Schema", StartDate = new DateTime(2026, 4, 7, 7, 0, 0), EndDate = new DateTime(2026, 4, 13, 18, 0, 0), Progress = 90 }, new TaskData { TaskID = 4, TaskName = "Authentication Module", StartDate = new DateTime(2026, 4, 8, 8, 0, 0), EndDate = new DateTime(2026, 4, 16, 17, 0, 0), Progress = 40 }, new TaskData { TaskID = 5, TaskName = "Testing & QA", StartDate = new DateTime(2026, 4, 11, 8, 0, 0), EndDate = new DateTime(2026, 4, 18, 18, 0, 0), Progress = 30 } }; } private List<SegmentModel> GetSegmentCollection() { var segments = new List<SegmentModel>(); // Task 1 – First segment exactly as you requested (8:00 AM Apr 6 → 7:00 AM Apr 7) segments.Add(new SegmentModel { Id = 1, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 6, 9, 20, 0), SegmentEndDate = new DateTime(2026, 4, 7, 7, 30, 0) }); segments.Add(new SegmentModel { Id = 2, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 8, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 15, 0, 0) }); segments.Add(new SegmentModel { Id = 3, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 10, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 10, 17, 0, 0) }); segments.Add(new SegmentModel { Id = 4, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 12, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 12, 12, 0, 0) }); segments.Add(new SegmentModel { Id = 5, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 14, 14, 0, 0), SegmentEndDate = new DateTime(2026, 4, 14, 18, 0, 0) }); // Task 2 – 4 segments segments.Add(new SegmentModel { Id = 6, TaskID = 2, SegmentStartDate = new DateTime(2026, 4, 6, 14, 0, 0), SegmentEndDate = new DateTime(2026, 4, 6, 18, 0, 0) }); segments.Add(new SegmentModel { Id = 7, TaskID = 2, SegmentStartDate = new DateTime(2026, 4, 8, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 16, 0, 0) }); segments.Add(new SegmentModel { Id = 8, TaskID = 2, SegmentStartDate = new DateTime(2026, 4, 10, 11, 0, 0), SegmentEndDate = new DateTime(2026, 4, 10, 15, 0, 0) }); segments.Add(new SegmentModel { Id = 9, TaskID = 2, SegmentStartDate = new DateTime(2026, 4, 15, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 15, 14, 0, 0) }); // Task 3 – 6 segments segments.Add(new SegmentModel { Id = 10, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 7, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 7, 12, 0, 0) }); segments.Add(new SegmentModel { Id = 11, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 7, 13, 30, 0), SegmentEndDate = new DateTime(2026, 4, 7, 17, 0, 0) }); segments.Add(new SegmentModel { Id = 12, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 8, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 13, 0, 0) }); segments.Add(new SegmentModel { Id = 13, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 9, 14, 0, 0), SegmentEndDate = new DateTime(2026, 4, 9, 18, 0, 0) }); segments.Add(new SegmentModel { Id = 14, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 12, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 12, 11, 30, 0) }); segments.Add(new SegmentModel { Id = 15, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 13, 15, 0, 0), SegmentEndDate = new DateTime(2026, 4, 13, 17, 0, 0) }); // Task 4 – 4 segments segments.Add(new SegmentModel { Id = 16, TaskID = 4, SegmentStartDate = new DateTime(2026, 4, 8, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 17, 0, 0) }); segments.Add(new SegmentModel { Id = 17, TaskID = 4, SegmentStartDate = new DateTime(2026, 4, 10, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 10, 14, 0, 0) }); segments.Add(new SegmentModel { Id = 18, TaskID = 4, SegmentStartDate = new DateTime(2026, 4, 14, 11, 0, 0), SegmentEndDate = new DateTime(2026, 4, 14, 16, 0, 0) }); segments.Add(new SegmentModel { Id = 19, TaskID = 4, SegmentStartDate = new DateTime(2026, 4, 16, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 16, 12, 0, 0) }); // Task 5 – 5 segments segments.Add(new SegmentModel { Id = 20, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 11, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 11, 13, 0, 0) }); segments.Add(new SegmentModel { Id = 21, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 12, 14, 0, 0), SegmentEndDate = new DateTime(2026, 4, 12, 18, 0, 0) }); segments.Add(new SegmentModel { Id = 22, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 15, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 15, 15, 0, 0) }); segments.Add(new SegmentModel { Id = 23, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 17, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 17, 11, 30, 0) }); segments.Add(new SegmentModel { Id = 24, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 18, 13, 0, 0), SegmentEndDate = new DateTime(2026, 4, 18, 17, 0, 0) }); return segments; } }

12 Replies

AG Ajithkumar Gopalakrishnan Syncfusion Team April 6, 2026 12:14 PM UTC

Hi Ramesh,

Greetings from Syncfusion Support,

Based on your query, when segment taskbar feature is enabled, tasks that are configured using only startDate and endDate, without a duration field, do not render properly in the Gantt Chart. We were able to reproduce this issue on our end. We have logged the reported issue “Segment taskbar does not render properly when duration field is not provided ” as a bug. Our team is working on a fix, and we plan to include it in the April 28, 2026 weekly release.


You can track the progress of the resolution by visiting the feedback link provided below:


Feedback link: https://www.syncfusion.com/feedback/73528/segment-taskbar-does-not-render-properly-when-duration-field-is-not-provided

Disclaimer: Inclusion of this solution in the weekly release may change due to other factors including but not limited to QA checks and works reprioritization.

Regards,
Ajithkumar G



RS Ramesh S April 7, 2026 04:24 AM UTC

I would like to render multiple segments within each task row in SfGantt.

The desired behavior is similar to the Syncfusion Blazor Gantt Chart Example – Airline Flight Scheduler, but with multiple segment bars displayed for each row.

Each segment should strictly adhere to its specified start and end date-time, without being affected by project management constraints such as holidays or weekends.

I hope this issue gets addressed, as it would enable the use of SfGantt for this specific requirement.



AG Ajithkumar Gopalakrishnan Syncfusion Team April 7, 2026 06:22 AM UTC

Hi Ramesh,

As mentioned earlier, based on your update, we will include the fix for the reported issue in the April 28, 2026 release, as promised.

Currently, the Gantt Chart provides support for weekends through the IncludeWeekend property. When this property is set to true, weekends are considered working days. For more details, please refer to the following User Guide documentation:

https://blazor.syncfusion.com/documentation/gantt-chart/scheduling-tasks#weekend-or-non-working-days

However, we do not currently support treating holidays as working days in the Gantt Chart. If holidays are configured, those dates will always be considered non‑working days and will be excluded from task scheduling and rendering. For more details, please refer to the following User Guide documentation:

https://blazor.syncfusion.com/documentation/gantt-chart/holidays

Please let us know if you need any further assistance.

Regards,
Ajithkumar G



RS Ramesh S April 10, 2026 07:21 AM UTC

Hi Ajith,

Thank you for your response.

In the bug report, it is mentioned that:
“Segment taskbar does not render properly when the duration field is not provided.”

Does this imply that segment taskbars are expected to render correctly when the Duration field is specified?

In my case, I am explicitly providing the Duration, and I observe the following behavior:

  • Segment taskbars render correctly only when the DateTime values are created with DateTimeKind.Local.

  • If I use the standard constructor, for example:
    new DateTime(2026, 4, 9, 14, 30, 0) (i.e., DateTimeKind.Unspecified),
    the segment taskbars do not render properly.

Additionally, I noticed another behavior:

  • When I use <GanttTemplates> and manually render the segments using custom C# calculations (pixel-based positioning), the taskbars render accurately.

  • However, when <GanttTemplates> is removed and the default segment rendering (GanttSegmentFields) is used, the segment taskbars are not rendered correctly.

Could you please clarify:

  1. Whether DateTimeKind (Local vs Unspecified) affects segment rendering in SfGantt?

  2. If there are any internal timezone or normalization mechanisms that require DateTimeKind.Local?

  3. Why the default segment rendering behaves differently compared to custom template rendering?

  4. Is there any documentation that explains these behaviors in detail, especially for hour-level timelines and segment rendering?

I have attached a minimal sample to reproduce this issue.

Thanks in advance for your clarification.


@page "/"

@using Syncfusion.Blazor.Gantt
@rendermode InteractiveWebAssembly

<h3>Syncfusion SfGantt - Segmented Tasks (No Subtasks) • .NET 10 Blazor WebAssembly</h3>
<p>Each task has 4–6 split segments. Timeline: Top tier = Day, Bottom tier = Hour. Project range = 15 days.</p>



<h3>🔥 Pixel-Accurate Segments (09:20 precise)</h3>

<SfGantt TValue="TaskData"
         DataSource="@Tasks"
         Height="600px"
         Width="100%"
         ProjectStartDate="@ProjectStart"
         ProjectEndDate="@ProjectEnd" IncludeWeekend="true"
         RowHeight="60">

    <GanttTaskFields Id="TaskID"
                     Name="TaskName"
                     StartDate="StartDate"
                     EndDate="EndDate">
    </GanttTaskFields>

    <!-- ❌ Disable default segments -->
    <GanttSegmentFields TValue="TaskData"
                        TSegments="SegmentData"
                        DataSource="@Segments"
                        PrimaryKey="Id"
                        ForeignKey="TaskID"
                        StartDate="StartDate"
                        Duration="Duration">
    </GanttSegmentFields>

    <GanttTimelineSettings TimelineUnitSize="80">
        <GanttTopTierSettings Unit="TimelineViewMode.Day" Format="ddd, dd MMM yyyy" />
        <GanttBottomTierSettings Unit="TimelineViewMode.Hour" />
    </GanttTimelineSettings>

    <!-- 🔥 CUSTOM RENDER -->
    <GanttTemplates TValue="TaskData">
        <TaskbarTemplate Context="ctx">
            @{
                var task = (TaskData)ctx;
            }

            @foreach (var seg in Segments.Where(s => s.TaskID == task.TaskID))
            {
                var left = GetLeft(seg.StartDate, task.StartDate);
                var width = GetWidth(seg);

                <div style="
                    position:absolute;
                    left:@($"{left}px");
                    width:@($"{width}px");
                    height:20px;
                    top:10px;
                    background:#3b82f6;
                    border-radius:4px;">
                </div>
            }
        </TaskbarTemplate>
    </GanttTemplates>

</SfGantt>

@code {

    DateTime ProjectStart = LocalDateTime(2026, 4, 5, 0, 0, 0);
    DateTime ProjectEnd = LocalDateTime(2026, 4, 10, 0, 0, 0);

    double PixelsPerHour = 80; // MUST match TimelineUnitSize

    List<TaskData> Tasks = new();
    List<SegmentData> Segments = new();
    
    protected override void OnInitialized()
    {
        Tasks = new()
        {
            new TaskData
            {
                TaskID = 1,
                TaskName = "Precise Task",
                StartDate = Local(2026,4,6,8,0,0),
                EndDate   = Local(2026,4,8,18,0,0)
            },

             new TaskData
            {
                TaskID = 2,
                TaskName = "Sample Task",
                StartDate = Local(2026,4,7,8,0,0),
                EndDate   = Local(2026,4,9,18,0,0)
            }
        };

        var start = Local(2026, 4, 6, 9, 20, 0);
        var end = Local(2026, 4, 6, 11, 30, 0);

        Segments = new()
        {
            new SegmentData
            {
                Id = 1,
                TaskID = 1,
                StartDate = start,
                Duration = (end - start).TotalHours
            },

             new SegmentData
            {
                Id = 2,
                TaskID = 1,
                StartDate =  Local(2026, 4, 7, 4, 20, 0),
                Duration = (Local(2026, 4, 7, 7, 30, 0) - Local(2026, 4, 7, 4, 20, 0)).TotalHours
            },

             new SegmentData
            {
                Id = 3,
                TaskID = 2,
                StartDate =  Local(2026, 4, 8, 6, 20, 0),
                Duration = (Local(2026, 4, 8, 9, 00, 0) - Local(2026, 4, 8, 6, 20, 0)).TotalHours
            }
        };
    }

    
    static  DateTime LocalDateTime(int y, int m, int d, int h, int min, int s)
    {
        return new DateTime(y, m, d, h, min, s, DateTimeKind.Local);
    }

    // 🔥 Pixel calculation
    double GetLeft(DateTime segmentStart, DateTime taskStart)
    {
        var hours = (segmentStart - taskStart).TotalHours;
        return hours * PixelsPerHour;
    }

    double GetWidth(SegmentData seg)
    {
        return seg.Duration * PixelsPerHour;
    }

    DateTime Local(int y, int m, int d, int h, int min, int s)
        => new DateTime(y, m, d, h, min, s, DateTimeKind.Local);

    public class TaskData
    {
        public int TaskID { get; set; }
        public string TaskName { get; set; } = "";
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
    }

    public class SegmentData
    {
        public int Id { get; set; }
        public int TaskID { get; set; }
        public DateTime StartDate { get; set; }
        public double Duration { get; set; }
    }

}




AG Ajithkumar Gopalakrishnan Syncfusion Team April 13, 2026 09:24 AM UTC

Hi Ramesh,

Query#1 - Does this imply that segment taskbars are expected to render correctly when the Duration field is specified?


We would like to clarify the behavior of the Gantt Chart. When segments are rendered based only on the provided start and end dates without a duration, the segment rendering was not properly validated internally. Due to this, we identified an issue and logged it as a bug titled “Segment taskbar does not render properly when the duration field is not provided”. This fix is planned for the April 28,2026 release.


When the Duration field is provided for segments, the Gantt Chart renders the segment taskbars correctly based on that value. The Gantt Chart prioritizes the Duration field for rendering. If the duration is not provided, it falls back to rendering based on the end date, which led to the reported issue.


Query#2 - Whether DateTimeKind (Local vs Unspecified) affects segment rendering in SfGantt?

The Gantt Chart renders taskbars strictly based on the supplied date and time values. Whether the dates are created using:


new DateTime(2026, 4, 9, 14, 30, 0)


new DateTime(y, m, d, h, min, s, DateTimeKind.Unspecified)


new DateTime(y, m, d, h, min, s, DateTimeKind.Local)


the final evaluated date‑time value is used for rendering the taskbar. We verified both Local and Unspecified kinds, and they render identically on the Gantt Chart.


The attached images demonstrate this behavior. The observed segment offset between segments is based on the configured DurationUnit, which by default is set to Day. Therefore, a difference of one day between segments is expected.


with local:



with Unspecified:



Query#3 - If there are any internal timezone or normalization mechanisms that require DateTimeKind.Local?

There is no internal validation or normalization logic that specifically depends on DateTimeKind.Local. Regardless of the DateTimeKind used, the Gantt Chart renders the taskbar based on the final resolved date‑time value.

Query#4 - Why the default segment rendering behaves differently compared to custom template rendering?

Based on the shared code snippet, we verified the sample and observed that when using a custom taskbar template, the segment rendering was incorrect because the left and width values were being manually calculated and applied.

with template:



without template:






When a taskbar template is not used, the segments render correctly based on the internally calculated values. These internal values are already validated and maintained by the Gantt Chart.

If a custom template is required, the left and width values should not be calculated manually. Instead, the internally calculated values returned by the GetRowTaskModel method should be used, as shown in the sample and documented approach.


We recommend following the documented sample below for correct template rendering:

<SfGantt @ref="gantt" TValue="TaskData" DataSource="@Tasks" Height="600px" Width="100%" ProjectStartDate="@ProjectStart" ProjectEndDate="@ProjectEnd" IncludeWeekend="true" RowHeight="60">

    <GanttTaskFields Id="TaskID"Name="TaskName"StartDate="StartDate"EndDate="EndDate"></GanttTaskFields>

    <!-- Disable default segments -->

    <GanttSegmentFields TValue="TaskData"TSegments="SegmentData"DataSource="@Segments"PrimaryKey="Id"ForeignKey="TaskID"StartDate="StartDate"Duration="Duration"></GanttSegmentFields>

    <GanttTimelineSettings TimelineUnitSize="80">

        <GanttTopTierSettings Unit="TimelineViewMode.Day" Format="ddd, dd MMM yyyy" />

        <GanttBottomTierSettings Unit="TimelineViewMode.Hour" />

    </GanttTimelineSettings>

    <!-- 🔥 CUSTOM RENDER -->

    <GanttTemplates TValue="TaskData">

        <TaskbarTemplate>

            @{

                var task = (context as TaskData);

                if (task == null)

                {

                    return;

                }

                var taskModel = gantt.GetRowTaskModel(task);

                List<GanttSegmentData> segments = taskModel.Segments;

                @if (segments != null && segments.Count() > 1)

                {

                    foreach (var segment in segments)

                    {

                        <div class="e-gantt-child-taskbar-inner-div e-gantt-child-taskbar e-segmented-taskbar" style=@("height:37px;position: absolute;left:" + segment.Left + "px; width:" + segment.Width + "px;") tabindex=-1 data-segment-index="@(segment.SegmentIndex)">

                            <div class="e-taskbar-left-resizer e-icon" style="margin-top: 5px; left:2px">

                            </div>

                            <div class="e-gantt-child-progressbar-inner-div e-gantt-child-progressbar" style="height:24px;width:@(segment.ProgressWidth + "px");border-radius: 0px;text-align: right;">

                            </div>

                            <div class="e-taskbar-right-resizer e-icon" style="margin-top: 5px;left:@((segment.Width) - 15)px">

                            </div>

                        </div>

                    }

                }

                else

                {

                    <div class="e-gantt-child-taskbar e-gantt-child-taskbar-inner-div" style="height:37px;" tabindex=-1>

                        <div class="e-gantt-child-progressbar-inner-div e-gantt-child-progressbar" style="height:24px;width:@(taskModel.ProgressWidth + "px");text-align: right;border-radius: 0px;">

                        </div>

                    </div>

                }

            }

        </TaskbarTemplate>

    </GanttTemplates>

</SfGantt>

 

@code {

 

    DateTime ProjectStart = LocalDateTime(2026, 4, 5, 0, 0, 0);

    DateTime ProjectEnd = LocalDateTime(2026, 4, 10, 0, 0, 0);

 

    double PixelsPerHour = 80; // MUST match TimelineUnitSize

List<TaskData> Tasks = new();

    List<SegmentData> Segments = new();

    private SfGantt<TaskData> gantt;


with template using our method:



Query#5 - Is there any documentation that explains these behaviors in detail, especially for hour-level timelines and segment rendering?


The following User Guide documents explain segment behavior and how segments are rendered in the Gantt Chart.

https://blazor.syncfusion.com/documentation/gantt-chart/splitting-and-merging-tasks


Please let us know if you need any further assistance.

Regards,
Ajithkumar G



RS Ramesh S April 17, 2026 05:54 AM UTC

Hi Ajithkumar,

I’m a bit confused about how the segments are being rendered. In the sample code, the first segment has a start date of April 6, 2026, at 9:20 AM with a duration of 2.166 hours. However, it is being rendered starting from April 6, 2026, at 8:00 AM and extending until around April 9, 2026, at 9:30 AM. The other segments are also rendered in the same way as the first one.

I also updated the DurationUnit to Hour, as shown below. But when I check the DurationUnit on a button click, it still shows as "Day", which suggests that the setting may not be applied correctly.

Is it possible to render the segments strictly based on the specified start date and duration? For example, the first segment should start at 9:20 AM and end at approximately 11:29 AM on the same day (April 6, 2026).


<GanttTaskFields Id="TaskID" Name="TaskName" DurationUnit="DurationUnit.Hour"
    StartDate="StartDate" EndDate="EndDate"></GanttTaskFields>

Thanks,

Ramesh S


Attachment: Syncfusion_Gantt3_35fe7030.jpg


AG Ajithkumar Gopalakrishnan Syncfusion Team April 20, 2026 07:26 AM UTC

Hi Ramesh,

Based on your query, our understanding is that the first segment start date does not begin as specified in the data source, and the DurationUnit property was not updated correctly on your end. We would like to clarify the behavior of the Gantt Chart. The first segment date mismatch occurs because the main task StartDate is set to StartDate = Local(2026, 4, 6, 8, 0, 0), while the segment StartDate is set to StartDate = Local(2026, 4, 6, 9, 20, 0).

By default, the Gantt Chart gives priority to the main task’s start date when rendering the first segment. Therefore, the first segment is rendered based on the task collection start date.

If you want the first segment to render using the same start date as the segment, you must update the main task’s StartDate to match the first segment’s StartDate. In that case, the segment will be rendered correctly on the Gantt Chart.

// Reported case

new TaskData

{

     TaskID = 1,

     TaskName = "Precise Task",

     StartDate = Local(2026,4,6,8,0,0),

     EndDate   = Local(2026,4,8,18,0,0),

     DurationUnit = "hour"

},


var start = Local(2026, 4, 6, 9, 20, 0);

var end = Local(2026, 4, 6, 11, 30, 0);

 

Segments = new()

{

    new SegmentData

    {

        Id = 1,

        TaskID = 1,

        StartDate = start,

        Duration = (end - start).TotalHours

    },

 

     new SegmentData

    {

        Id = 2,

        TaskID = 1,

        StartDate =  Local(2026, 4, 7, 4, 20, 0),

        Duration = (Local(2026, 4, 7, 7, 30, 0) - Local(2026, 4, 7, 4, 20, 0)).TotalHours

    },


// Solution

new TaskData

{

     TaskID = 1,

     TaskName = "Precise Task",

     StartDate = Local(2026,4,6,9,20,0),

     EndDate   = Local(2026,4,8,18,0,0),

     DurationUnit = "hour"

},


var start = Local(2026, 4, 6, 9, 20, 0);

var end = Local(2026, 4, 6, 11, 30, 0);

 

Segments = new()

{

    new SegmentData

    {

        Id = 1,

        TaskID = 1,

        StartDate = start,

        Duration = (end - start).TotalHours

    },

 

     new SegmentData

    {

        Id = 2,

        TaskID = 1,

        StartDate =  Local(2026, 4, 7, 4, 20, 0),

        Duration = (Local(2026, 4, 7, 7, 30, 0) - Local(2026, 4, 7, 4, 20, 0)).TotalHours

    },




Additionally, since the DurationUnit is not reflected on your end, we suspect that it has been updated only in GanttTaskFields. To apply the change correctly, the DurationUnit must also be updated in the task data collection.

By default, the Gantt Chart working time is set from 8:00 AM to 5:00 PM. If you require a 24-hour working schedule, you need to update the GanttDayWorkingTime property accordingly.

Please refer to the code snippet below and the sample for implementation details.

<SfGantt @ref="gantt" TValue="TaskData"  DataSource="@Tasks" Height="600px" Width="100%" ProjectStartDate="@ProjectStart" ProjectEndDate="@ProjectEnd" IncludeWeekend="true" RowHeight="60">

    <GanttTaskFields Id="TaskID" Name="TaskName" StartDate="StartDate" EndDate="EndDate" DurationUnit="DurationUnit"></GanttTaskFields>

    …

   <GanttDayWorkingTimeCollection>

        <GanttDayWorkingTime From="0" To="24"></GanttDayWorkingTime>

    </GanttDayWorkingTimeCollection>

</SfGantt>

new
TaskData

{

     TaskID = 1,

     TaskName = "Precise Task",

     StartDate = Local(2026,4,6,9,20,0),

     EndDate   = Local(2026,4,8,18,0,0),

     DurationUnit = "hour"

},


Sample link: https://blazorplayground.syncfusion.com/embed/rXhnZzLjicTRSgJV?appbar=true&editor=true&result=true&errorlist=true&theme=fluent2

For more details, please refer to the following User Guide documentation:


https://blazor.syncfusion.com/documentation/gantt-chart/scheduling-tasks#mapping-the-duration-unit-field
https://blazor.syncfusion.com/documentation/gantt-chart/scheduling-tasks#working-time-range

Please let us know if you need any further assistance.

Regards,
Ajithkumar G




RS Ramesh S April 22, 2026 10:47 AM UTC

Hi Ajithkumar,

Thank you for your detailed explanation, sample code, and documentation.

I have a couple of follow-up questions:

Is it possible to disable the internal calculations and render all segments in each task row strictly based on the start date and duration (or even with end date of the segment - which is already reported as bug) defined in the SegmentData object? In my previous message, I referred to the first segment as an example, but this requirement applies to all segments across all task rows—they should align exactly with their respective start date times and durations (in hours).

Additionally, is it possible to move a segment from one task row to another using drag-and-drop? If not, can we handle mouse interactions (such as click, move, and mouse down events) on segments and task rows to implement this behavior ourselves? I actually already implemented drag and drop of range bars from one row to another using mouse events in SfChart control..

Thanks,



AG Ajithkumar Gopalakrishnan Syncfusion Team April 23, 2026 03:38 AM UTC

Hi Ramesh,

Query#1 -
Rendering segments strictly based on SegmentData (without internal calculations)

Currently, it is not possible to disable the internal scheduling calculations in the Syncfusion Gantt control or to render segments purely based on the StartDate and Duration (or EndDate) defined in the SegmentData object.

Explanation

In the Gantt Chart architecture, the parent task is always the primary scheduling entity, and segmented tasks are rendered relative to the main task’s schedule. Internally, the Gantt Chart performs several mandatory calculations that affect how segments are rendered, including:

  • Alignment with the parent task StartDate
  • Normalization based on DurationUnit


Query#2 - Drag‑and‑drop of segments between task rows

At present, drag‑and‑drop of a segment from one task row to another is not supported in Gantt Chart.

Segments are tightly bound to their parent task, and changing a segment’s TaskID through drag‑and‑drop is not exposed via any built‑in API or event. Allowing this natively would conflict with internal task duration recalculation, dependency handling, and virtualization mechanisms.

Mouse interaction on segments

The Gantt Chart control also does not provide segment‑level mouse events such as:

  • mousedown
  • mousemove
  • mouseup
  • click

Only row‑level and taskbar‑level interactions are available. This means segment‑to‑row drag handling cannot be implemented directly through Gantt Chart events.

Please let us know if you have any further questions or need additional clarification.

Regards,
Ajithkumar G



AG Ajithkumar Gopalakrishnan Syncfusion Team April 29, 2026 12:47 PM UTC

Hi Ramesh,

We appreciate your patience.

We are glad to announce that we have included the fix for the issue “Segment taskbar does not render properly when duration field is not provided” in our 33.2.4 release. So please upgrade to our latest version of the Syncfusion package to resolve the reported issue.

Root Cause: The segment rendering logic always adjusts start times to the default day start. This adjustment is applied even when the timeline is set to Hours or Minutes, which changes valid segment start times. As a result, segment-based scheduling does not work correctly because hour-level segment data is treated like day-level data.

Solution: Update the date‑normalization and non‑working day logic so that default start-time alignment is skipped for Hour and Minute timelines. This allows segment start and end times to remain unchanged, ensuring segment taskbars render correctly without requiring a Duration.

Sample link: https://blazorplayground.syncfusion.com/embed/VNhxjzrOpTBkvlzf?appbar=true&editor=true&result=true&errorlist=true&theme=fluent2

Feedback: https://www.syncfusion.com/feedback/73528/segment-taskbar-does-not-render-properly-when-duration-field-is-not-provided

Release notes: https://blazor.syncfusion.com/documentation/release-notes/33.2.4?type=all#gantt-chart

We thank you for your support and appreciate your patience in waiting for this release. Please get back to us if you need any further assistance.

Regards,

Ajithkumar G



RS Ramesh S May 1, 2026 07:36 AM UTC

Hi Ajithkumar,

Thank you for the update and for releasing the bug fix — the changes look promising.

Regarding my earlier query on “Query #1 – Rendering segments strictly based on SegmentData (without internal calculations)”, I understand your response mentioned that it is not possible to disable internal scheduling calculations in the Syncfusion Gantt control or to render segments purely based on the StartDate and Duration (or EndDate) defined in SegmentData.

However, based on my testing, it appears this behavior can be achieved under certain conditions:

  • IncludeWeekend is set to true
  • DurationUnit is set to DurationUnit.Hour
  • Each task’s start date is aligned with the start date of its first segment
  • Task Progress is set to 100

With this configuration, all segments seem to render strictly according to their defined start and end times. For example, the following segments (all falling on April 8, 2026) across five tasks are rendered accurately:

segments.Add(new SegmentModel { Id = 2, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 8, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 15, 0, 0) });

segments.Add(new SegmentModel { Id = 7, TaskID = 2, SegmentStartDate = new DateTime(2026, 4, 8, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 16, 0, 0) });

segments.Add(new SegmentModel { Id = 12, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 8, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 13, 0, 0) });

segments.Add(new SegmentModel { Id = 16, TaskID = 4, SegmentStartDate = new DateTime(2026, 4, 8, 9, 25, 0), SegmentEndDate = new DateTime(2026, 4, 8, 17, 45, 0) });

segments.Add(new SegmentModel { Id = 20, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 8, 5, 45, 0), SegmentEndDate = new DateTime(2026, 4, 8, 12, 30, 0) });


Additionally, I have a couple of follow-up questions:

  1. Performance with large datasets
    I am working with approximately 3,500 tasks and 14,500 segments.
    Currently, even loading 150 tasks with ~1,250 segments (about 5–10 segments per task) sometimes causes the Blazor page to freeze or slows down other functionalities.
    • Is this volume of data supported efficiently by SfGantt?
    • Are there recommended strategies or configurations to improve performance for such large datasets?
  2. Custom tooltip for segments

Currently, the tooltip displayed on segment hover shows the same default information for all segments. Is it possible to display unique, custom tooltip content for each segment?

I was able to achieve this using <SfTooltip> within <GanttTemplates>, but it appears to be quite heavy and negatively impacts page performance. Is there a more efficient approach to implement custom tooltips for segments without affecting rendering performance?


SfGantt2.jpg



@page "/"
@using Syncfusion.Blazor.Gantt


<h3>Syncfusion SfGantt - Segmented Tasks (No Subtasks) • .NET 10 Blazor WebAssembly</h3><p>Each task has 4–6 split segments. Timeline: Top tier = Day, Bottom tier = Hour. Project range = 15 days.</p>
<SfGantt TValue="TaskData"
         DataSource="@taskCollection"
         Height="700px"
         Width="100%"
         ProjectStartDate="@projectStart"
         ProjectEndDate="@projectEnd"
         DurationUnit="DurationUnit.Hour"
         IncludeWeekend="true"
         EnableRowVirtualization="false">
    <GanttTaskFields Id="TaskID"
                     Name="TaskName"
                     StartDate="StartDate"
                     EndDate="EndDate"
                     Progress="Progress">
    </GanttTaskFields><!-- Correct segmented tasks binding (official way) -->
    <GanttSegmentFields TValue="TaskData"
                        TSegments="SegmentModel"
                        PrimaryKey="Id"
                        ForeignKey="TaskID"
                        StartDate="SegmentStartDate"
                        EndDate="SegmentEndDate"
                        DataSource="@segmentCollection">
    </GanttSegmentFields><!-- Timeline Settings -->
    <GanttTimelineSettings TimelineUnitSize="60">
        <GanttTopTierSettings Unit="TimelineViewMode.Day" Format="ddd, MMM dd"></GanttTopTierSettings>
        <GanttBottomTierSettings Unit="TimelineViewMode.Hour" Format="HH:mm"></GanttBottomTierSettings>
    </GanttTimelineSettings>
    <GanttDayWorkingTimeCollection>
        <GanttDayWorkingTime From="0" To="24"></GanttDayWorkingTime>
    </GanttDayWorkingTimeCollection>
    <GanttColumns>
        <GanttColumn Field="TaskID" HeaderText="ID" Width="80" IsPrimaryKey="true"></GanttColumn>
        <GanttColumn Field="TaskName" HeaderText="Task Name" Width="280"></GanttColumn>
        <GanttColumn Field="StartDate" HeaderText="Overall Start" Width="170" Format="M/d/yyyy HH:mm"></GanttColumn>
        <GanttColumn Field="EndDate" HeaderText="Overall End" Width="170" Format="M/d/yyyy HH:mm"></GanttColumn>
        <GanttColumn Field="Progress" HeaderText="Progress (%)" Width="110"></GanttColumn>
    </GanttColumns>
    <GanttEditSettings AllowEditing="true" AllowAdding="true" AllowDeleting="true" AllowTaskbarEditing="true" Mode="Syncfusion.Blazor.Gantt.EditMode.Dialog"></GanttEditSettings>
</SfGantt>

@code {
    private DateTime projectStart = new DateTime(2026, 4, 6, 0, 0, 0);
    private DateTime projectEnd = new DateTime(2026, 4, 21, 23, 59, 59);

    private List<TaskData> taskCollection = new();
    private List<SegmentModel> segmentCollection = new();

    protected override void OnInitialized()
    {
        taskCollection = GetTaskCollection();
        segmentCollection = GetSegmentCollection();
    }

    public class TaskData
    {
        public int TaskID { get; set; }
        public string TaskName { get; set; } = string.Empty;
        public DateTime StartDate { get; set; }
        public DateTime EndDate { get; set; }
        public int Progress { get; set; }
    }

    public class SegmentModel
    {
        public int Id { get; set; }
        public int TaskID { get; set; }
        public DateTime SegmentStartDate { get; set; }
        public DateTime SegmentEndDate { get; set; }
    }

    private List<TaskData> GetTaskCollection()
    {
        return new List<TaskData>
        {
            new TaskData { TaskID = 1, TaskName = "UI Wireframing",      StartDate = new DateTime(2026, 4, 6, 9, 20, 0), EndDate = new DateTime(2026, 4, 14, 19, 0, 0), Progress = 100 },
            new TaskData { TaskID = 2, TaskName = "Backend API Design",   StartDate = new DateTime(2026, 4, 6, 14, 0, 0), EndDate = new DateTime(2026, 4, 15, 15, 0, 0), Progress = 1000 },
            new TaskData { TaskID = 3, TaskName = "Database Schema",      StartDate = new DateTime(2026, 4, 7, 8, 0, 0),  EndDate = new DateTime(2026, 4, 13, 18, 0, 0), Progress = 100 },
            new TaskData { TaskID = 4, TaskName = "Authentication Module", StartDate = new DateTime(2026, 4, 8, 9, 25, 0),  EndDate = new DateTime(2026, 4, 16, 17, 0, 0), Progress = 100},
            new TaskData { TaskID = 5, TaskName = "Testing & QA",         StartDate = new DateTime(2026, 4, 8, 5, 45, 0), EndDate = new DateTime(2026, 4, 18, 18, 0, 0), Progress = 100 }
        };
    }

    private List<SegmentModel> GetSegmentCollection()
    {
        var segments = new List<SegmentModel>();

        // Task 1 – First segment exactly as you requested (8:00 AM Apr 6 → 7:00 AM Apr 7)
        segments.Add(new SegmentModel { Id = 1, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 6, 9, 20, 0), SegmentEndDate = new DateTime(2026, 4, 7, 7, 30, 0) });
        segments.Add(new SegmentModel { Id = 2, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 8, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 15, 0, 0) });
        segments.Add(new SegmentModel { Id = 3, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 10, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 10, 17, 0, 0) });
        segments.Add(new SegmentModel { Id = 4, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 12, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 12, 12, 0, 0) });
        segments.Add(new SegmentModel { Id = 5, TaskID = 1, SegmentStartDate = new DateTime(2026, 4, 14, 14, 0, 0), SegmentEndDate = new DateTime(2026, 4, 14, 18, 0, 0) });

        // Task 2 – 4 segments
        segments.Add(new SegmentModel { Id = 6, TaskID = 2, SegmentStartDate = new DateTime(2026, 4, 6, 14, 0, 0), SegmentEndDate = new DateTime(2026, 4, 6, 18, 0, 0) });
        segments.Add(new SegmentModel { Id = 7, TaskID = 2, SegmentStartDate = new DateTime(2026, 4, 8, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 16, 0, 0) });
        segments.Add(new SegmentModel { Id = 8, TaskID = 2, SegmentStartDate = new DateTime(2026, 4, 10, 11, 0, 0), SegmentEndDate = new DateTime(2026, 4, 10, 15, 0, 0) });
        segments.Add(new SegmentModel { Id = 9, TaskID = 2, SegmentStartDate = new DateTime(2026, 4, 15, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 15, 14, 0, 0) });

        // Task 3 – 6 segments
        segments.Add(new SegmentModel { Id = 10, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 7, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 7, 12, 0, 0) });
        segments.Add(new SegmentModel { Id = 11, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 7, 13, 30, 0), SegmentEndDate = new DateTime(2026, 4, 7, 17, 0, 0) });
        segments.Add(new SegmentModel { Id = 12, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 8, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 8, 13, 0, 0) });
        segments.Add(new SegmentModel { Id = 13, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 9, 14, 0, 0), SegmentEndDate = new DateTime(2026, 4, 9, 18, 0, 0) });
        segments.Add(new SegmentModel { Id = 14, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 12, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 12, 11, 30, 0) });
        segments.Add(new SegmentModel { Id = 15, TaskID = 3, SegmentStartDate = new DateTime(2026, 4, 13, 15, 0, 0), SegmentEndDate = new DateTime(2026, 4, 13, 17, 0, 0) });

        // Task 4 – 4 segments
        segments.Add(new SegmentModel { Id = 16, TaskID = 4, SegmentStartDate = new DateTime(2026, 4, 8, 9, 25, 0), SegmentEndDate = new DateTime(2026, 4, 8, 17, 45, 0) });
        segments.Add(new SegmentModel { Id = 17, TaskID = 4, SegmentStartDate = new DateTime(2026, 4, 10, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 10, 14, 0, 0) });
        segments.Add(new SegmentModel { Id = 18, TaskID = 4, SegmentStartDate = new DateTime(2026, 4, 14, 11, 0, 0), SegmentEndDate = new DateTime(2026, 4, 14, 16, 0, 0) });
        segments.Add(new SegmentModel { Id = 19, TaskID = 4, SegmentStartDate = new DateTime(2026, 4, 16, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 16, 12, 0, 0) });

        // Task 5 – 5 segments
        segments.Add(new SegmentModel { Id = 20, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 8, 5, 45, 0), SegmentEndDate = new DateTime(2026, 4, 8, 12, 30, 0) });
        segments.Add(new SegmentModel { Id = 21, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 11, 9, 0, 0), SegmentEndDate = new DateTime(2026, 4, 11, 13, 0, 0) });
        segments.Add(new SegmentModel { Id = 22, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 12, 14, 0, 0), SegmentEndDate = new DateTime(2026, 4, 12, 18, 36, 0) });
        segments.Add(new SegmentModel { Id = 23, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 15, 10, 0, 0), SegmentEndDate = new DateTime(2026, 4, 15, 15, 0, 0) });
        segments.Add(new SegmentModel { Id = 24, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 17, 8, 0, 0), SegmentEndDate = new DateTime(2026, 4, 17, 11, 30, 0) });
        segments.Add(new SegmentModel { Id = 25, TaskID = 5, SegmentStartDate = new DateTime(2026, 4, 18, 13, 0, 0), SegmentEndDate = new DateTime(2026, 4, 18, 17, 50, 0) });

        return segments;
    }
}


SJ Sridharan Jayabalan Syncfusion Team May 4, 2026 03:11 PM UTC

Ramesh,

 

Query 1 - Performance with large datasets:

Based on your query, we understand that loading 150 tasks with approximately 1,250 segments (around 5–10 segments per task) occasionally causes the Blazor page to freeze or results in performance degradation across other functionalities.

To validate this scenario, we prepared a sample using the code snippets you shared and modified the dataSource accordingly. After verification, we observed that the initial load and all actions are working as expected without any noticeable time delay or freeze.

Kindly refer to the attached sample and video demonstration for your reference.

Video - Refer attachments.

 

If still the issue persists, replicate the issue with the attached sample and revert us back.

 

Query 2 - Custom tooltip for segments:

We have considered your requirement "Is it possible to display unique, custom tooltip content for each segment?" as a feature from our end, but we do not have any immediate plans to implement this feature. 


The status of implementation can be tracked through the feedback portal link below:

Any relevant updates regarding the feature's implementation will be communicated to you through the feedback link.

 

 

Regards,

Sridharan


Attachment: PerformanceVideo_e3be0aa2.zip

Loader.
Up arrow icon