From 194ceb4434470f808ed9b6b063dbc18cb1116328 Mon Sep 17 00:00:00 2001 From: Nithya Date: Tue, 4 Nov 2025 19:03:01 +0530 Subject: [PATCH 1/2] 989389: Restored and updated content post revert in dev branch Signed-off-by: Nithya --- blazor-toc.html | 3 +- blazor/gantt-chart/cell-selection.md | 8 +- blazor/gantt-chart/criticalpath.md | 36 +- blazor/gantt-chart/customize-pdf-export.md | 1430 +++++++++++++++++ blazor/gantt-chart/data-markers.md | 28 +- blazor/gantt-chart/deleting-tasks.md | 16 +- blazor/gantt-chart/editing-tasks.md | 286 ++-- blazor/gantt-chart/event-markers.md | 61 +- blazor/gantt-chart/header-and-footer.md | 206 +++ blazor/gantt-chart/holidays.md | 70 +- .../open-add-edit-dialog-dynamically.md | 35 +- blazor/gantt-chart/images/cell-edit.png | Bin 0 -> 29451 bytes blazor/gantt-chart/images/duration-manual.PNG | Bin 0 -> 3712 bytes blazor/gantt-chart/images/editing-dialog.png | Bin 0 -> 38540 bytes blazor/gantt-chart/images/endDate-manual.PNG | Bin 0 -> 1226 bytes .../gantt-chart/images/startDate-manual.PNG | Bin 0 -> 1233 bytes .../gantt-chart/images/user-interaction.png | Bin 0 -> 37572 bytes blazor/gantt-chart/labels.md | 53 +- blazor/gantt-chart/managing-tasks.md | 129 +- blazor/gantt-chart/pdf-export.md | 1230 +------------- blazor/gantt-chart/predecessor-validation.md | 21 +- blazor/gantt-chart/resource-view.md | 34 +- blazor/gantt-chart/resources.md | 54 +- blazor/gantt-chart/scheduling-tasks.md | 346 ++-- blazor/gantt-chart/splitter.md | 22 +- blazor/gantt-chart/taskbar-editing.md | 110 +- blazor/gantt-chart/tool-bar.md | 203 +-- .../gantt-chart/top-tier-and-bottom-tier.md | 177 +- blazor/gantt-chart/zooming.md | 196 ++- 29 files changed, 2788 insertions(+), 1966 deletions(-) create mode 100644 blazor/gantt-chart/customize-pdf-export.md create mode 100644 blazor/gantt-chart/header-and-footer.md create mode 100644 blazor/gantt-chart/images/cell-edit.png create mode 100644 blazor/gantt-chart/images/duration-manual.PNG create mode 100644 blazor/gantt-chart/images/editing-dialog.png create mode 100644 blazor/gantt-chart/images/endDate-manual.PNG create mode 100644 blazor/gantt-chart/images/startDate-manual.PNG create mode 100644 blazor/gantt-chart/images/user-interaction.png diff --git a/blazor-toc.html b/blazor-toc.html index f912940a80..c29cf11361 100644 --- a/blazor-toc.html +++ b/blazor-toc.html @@ -3131,7 +3131,8 @@
  • Excel Export
  • PDF Export
  • Timezone
  • diff --git a/blazor/gantt-chart/cell-selection.md b/blazor/gantt-chart/cell-selection.md index 484e6b0311..b346f2282f 100644 --- a/blazor/gantt-chart/cell-selection.md +++ b/blazor/gantt-chart/cell-selection.md @@ -13,7 +13,7 @@ Cell selection in the Gantt Chart component enables interactive selection of spe ## Single cell selection -Single cell selection in the Gantt chart is enabled by setting [GanttSelectionSettings.Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttSelectionSettings.html#Syncfusion_Blazor_Gantt_GanttSelectionSettings_Mode) to **Cell** and [selectionSettings.type](https://ej2.syncfusion.com/angular/documentation/api/gantt/selectionSettings/#type) to **Single**. This allows selecting only one cell at a time. +Single cell selection in the Gantt chart is enabled by setting [GanttSelectionSettings.Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttSelectionSettings.html#Syncfusion_Blazor_Gantt_GanttSelectionSettings_Mode) to **Cell** and [SelectionSettings.Type](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttSelectionSettings.html#Syncfusion_Blazor_Gantt_GanttSelectionSettings_Type) to **Single**. This allows selecting only one cell at a time. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -70,7 +70,7 @@ Single cell selection in the Gantt chart is enabled by setting [GanttSelectionSe ## Multiple cell selection -Multiple cell selection in the Gantt Chart is enabled by setting [selectionSettings.mode](https://ej2.syncfusion.com/angular/documentation/api/gantt/selectionSettings/#mode) to **Cell** and [selectionSettings.type](https://ej2.syncfusion.com/angular/documentation/api/gantt/selectionSettings/#type) to **Multiple**. This allows selecting multiple cells at a time by holding the Ctrl key while clicking on each desired cell. +Multiple cell selection in the Gantt Chart is enabled by setting [selectionSettings.mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttSelectionSettings.html#Syncfusion_Blazor_Gantt_GanttSelectionSettings_Mode) to **Cell** and [SelectionSettings.Type](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttSelectionSettings.html#Syncfusion_Blazor_Gantt_GanttSelectionSettings_Type) to **Multiple**. This allows selecting multiple cells at a time by holding the Ctrl key while clicking on each desired cell. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -194,7 +194,7 @@ Select a specific cell in the Gantt Chart by calling the [SelectCellAsync](http ## Customize cell selection action -You may customize cell selection behavior in the Gantt Chart using [cellSelecting](https://ej2.syncfusion.com/angular/documentation/api/gantt/events/#cellselecting), [cellSelected](https://ej2.syncfusion.com/angular/documentation/api/gantt/events/#cellselected), [cellDeselecting](https://ej2.syncfusion.com/angular/documentation/api/gantt/events/#celldeselecting), and [cellDeselected](https://ej2.syncfusion.com/angular/documentation/api/gantt/events/#celldeselected) events. +You may customize cell selection behavior in the Gantt Chart using [CellSelecting](https://blazor.syncfusion.com/documentation/gantt-chart/events#cellselecting), [CellSelected](https://blazor.syncfusion.com/documentation/gantt-chart/events#cellselected), [CellDeselecting](https://blazor.syncfusion.com/documentation/gantt-chart/events#celldeselecting), and [CellDeselected](https://blazor.syncfusion.com/documentation/gantt-chart/events#celldeselected) events. The following sample demonstrates selection is canceled in the `cellSelecting` event when the **TaskName** is **Perform Soil test**. @@ -301,4 +301,4 @@ The following sample demonstrates selection is canceled in the `cellSelecting` e - [Accessibility in Blazor Gantt Chart](https://blazor.syncfusion.com/documentation/gantt-chart/accessibility) - [Blazor Gantt Chart Feature Tour](https://www.syncfusion.com/blazor-components/blazor-gantt-chart) -- [Blazor Gantt Chart Example](https://blazor.syncfusion.com/demos/gantt-chart/default-functionalities?theme=bootstrap5) +- [Blazor Gantt Chart Example](https://blazor.syncfusion.com/demos/gantt-chart/default-functionalities?theme=bootstrap5) \ No newline at end of file diff --git a/blazor/gantt-chart/criticalpath.md b/blazor/gantt-chart/criticalpath.md index 0ecca35627..95c5e1a9a7 100644 --- a/blazor/gantt-chart/criticalpath.md +++ b/blazor/gantt-chart/criticalpath.md @@ -1,19 +1,45 @@ --- layout: post title: Critical Path in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about critical path in Syncfusion Blazor Gantt Chart component and much more details. +description: Learn here all about Critical path in Syncfusion Blazor Gantt Chart component and much more details. platform: Blazor -component: Gantt Chart +component: Critical path documentation: ug --- # Critical Path in Blazor Gantt Chart component -The critical path in a project is indicated by a single task or a series of tasks. If a task in critical path is delayed, the entire project will be delayed. A task is considered to be critical if any delay to this task would affect the project end date. +The critical path represents the longest sequence of dependent tasks that determines the minimum project duration. Tasks on the critical path have zero or negative [SlackValue](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttCriticalPathSettings.html#Syncfusion_Blazor_Gantt_GanttCriticalPathSettings_SlackValue) (float), meaning any delay in these tasks directly impacts the overall project completion date. The Blazor Gantt Chart component automatically calculates and highlights critical tasks in red with emphasized dependency connector lines when the [EnableCriticalPath](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_EnableCriticalPath) property is enabled. Critical path analysis helps identify which tasks require immediate attention and cannot be delayed without affecting project deadlines. -The critical path can be enabled in the Gantt Chart by using the built-in toolbar button or by setting the [EnableCriticalPath](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_EnableCriticalPath) property to true in the [SfGantt](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html) component. +## Understanding critical path calculation -The following code example shows how to display the critical path in the Gantt control: +The component uses Critical Path Method (CPM) principles to identify critical tasks through a comprehensive calculation process that analyzes task dependencies, timing relationships, and slack values to determine which tasks have no scheduling flexibility. A task becomes critical when it has zero or negative slack, meaning any delay (even by a minute) shifts the entire project end date. This occurs because critical tasks are linked through dependencies, creating a chain reaction where delays propagate across the dependency network, ultimately affecting the project completion date. + +**Project end date determination**: The calculation begins by determining the overall project end date. If the [ProjectEndDate](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ProjectEndDate) property is provided, it uses that value as the project completion reference. If `ProjectEndDate` is not specified, the component automatically calculates the project end date by examining all task end dates in the data source to find the latest completion point. This reference point determines how much delay each task can tolerate without affecting project completion. + +**Slack value calculation**: For each task, the component calculates slack by measuring the time difference between the task's end date and the project end date. Slack represents how much time a task can be delayed without affecting the project completion: +- **Zero slack**: The task must finish exactly on time. Any delay will push back the project end date, making it critical +- **Negative slack**: The task is already behind schedule or creates scheduling conflicts. This occurs when a task's end date is beyond the project end date, or when dependency relationships create impossible timing constraints. + +**Parent-Child task relationships**: In projects with hierarchical tasks, the critical path calculation focuses on dependencies rather than the parent-child structure used for task organization. For example, if Task 1.1 (a child task) depends on Task 2 (a parent task), only the tasks directly linked by the dependency are evaluated for criticality based on their timing. A parent task like Task 2 being critical does not automatically make its child tasks (e.g., Task 2.1, Task 2.2) critical, nor does a critical child task imply a critical parent. The component evaluates each task’s slack independently, ensuring that only tasks with zero or negative slack, driven by their dependency constraints, are marked as critical. This distinction allows precise identification of critical tasks without conflating organizational hierarchy with scheduling dependencies. + +**Dependency-based analysis**: The component analyzes different dependency relationship types to determine slack impacts: +- **Finish-to-Start**: When a predecessor task ends after its successor should start, negative slack results from the timing conflict +- **Start-to-Start**: When a predecessor starts after its successor should start, the component calculates negative slack based on scheduling impossibility +- **Finish-to-Finish** and **Start-to-Finish**: These relationships can also produce negative slack when timing conflicts exist between connected tasks +- **Offset and scheduling mode handling**: When dependencies include time offsets (e.g., "+2 days" or "-1 hour"), the component adjusts slack calculations by factoring in the offset duration. The calculation differs for automatically scheduled versus manually scheduled tasks: automatic tasks use forward and backward pass algorithms to compute slack, while manual tasks compare their end dates directly against the project completion date. + +**Progress consideration**: The component considers task completion progress. Only tasks with less than 100% progress can be marked as critical, since completed tasks cannot cause future delays. Tasks that end on or beyond the project end date automatically become critical regardless of their dependency relationships, as they directly determine the project completion timing. + +## Critical path setup and configuration + +The Critical Path feature in the Blazor Gantt component highlights tasks that directly impact the overall project completion date. To enable this functionality, ensure that the data source must contain tasks with valid start dates, end dates, and task dependencies properly mapped through the [Dependency](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Dependency) field in [TaskFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html). + +Enable critical path display by setting [EnableCriticalPath](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_EnableCriticalPath) to **true**, or add the `CriticalPath` option to the [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_Toolbar) array to allow interactive toggling. The [GetCriticalTasks](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_Toolbar) method retrieves all tasks identified as critical at runtime. + +The critical path recalculates automatically when task properties change, including start and end dates, duration modifications, dependency updates, or progress adjustments. This ensures the visualization remains accurate throughout project management workflows. + +The following example demonstrates enabling critical path analysis: {% tabs %} {% highlight razor tabtitle="Index.razor" %} diff --git a/blazor/gantt-chart/customize-pdf-export.md b/blazor/gantt-chart/customize-pdf-export.md new file mode 100644 index 0000000000..66c1525687 --- /dev/null +++ b/blazor/gantt-chart/customize-pdf-export.md @@ -0,0 +1,1430 @@ +--- +layout: post +title: Customize PDF exporting in Syncfusion Blazor Gantt Chart +description: Learn here all about Customize PDF exporting in Syncfusion Blazor Gantt Chart component and much more. +platform: Blazor +control: Customize pdf export +documentation: ug +--- + +# To customize PDF export + +Customizing PDF export in the Blazor Gantt Chart component allows tailoring exported documents for specific needs, using [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) to adjust file names, page orientation, size, columns, headers, footers, timelines, and templates. Ensuring focused content like selected rows or styled taskbars and [AllowPdfExport](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowPdfExport) enabled. Use [PdfExporting](https://blazor.syncfusion.com/documentation/gantt-chart/events#pdfexporting) and [PdfExported](https://blazor.syncfusion.com/documentation/gantt-chart/events#pdfexported) events for pre-export and post-export modifications, and [PdfQueryTaskbarInfo](https://blazor.syncfusion.com/documentation/gantt-chart/events#pdfquerytaskbarinfo) for taskbar styling. + +## Customize file name + +Set the exported PDF file name using the [FileName](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_FileName) property in [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html), such as **ProjectSchedule.pdf**, for personalized document naming. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Navigations + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); + exportProperties.FileName = "ProjectSchedule.pdf"; + await Gantt.ExportToPdfAsync(exportProperties); + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BjBSCZNAhALZXWKG?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## How to change the page orientation + +You can customize the page orientation of the exported PDF document in the Blazor Gantt chart by using the [PageOrientation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_PageOrientation) property in the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. +This property allows you to choose between [Portrait](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PageOrientation.html#Syncfusion_Blazor_Grids_PageOrientation_Portrait) (default) and [Landscape](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PageOrientation.html#Syncfusion_Blazor_Grids_PageOrientation_Landscape) orientations based on your layout requirements. Use `Portrait` for documents that require more vertical space, and `Landscape` when you need to fit more columns or wider taskbars. + +The following code snippet demonstrates how to set the page orientation to `Landscape` for the exported PDF document: + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Navigations + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); + exportProperties.PageOrientation = Syncfusion.Blazor.Grids.PageOrientation.Landscape; + await Gantt.ExportToPdfAsync(exportProperties); + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BtVyMjNgBzDbCnDU?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Customize page size + +Page size can be customized for the exported document using the [PageSize](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfPageSize.html) property in [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html). +The supported page sizes are: + +* Letter +* Note +* Legal +* A0 to A9 +* B0 to B5 +* Archa +* Archb +* Archc +* Archd +* Arche +* Flsa +* HalfLetter +* Letter11x17 +* Ledger + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Navigations + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); + exportProperties.PageSize = Syncfusion.Blazor.Grids.PdfPageSize.A4; + await Gantt.ExportToPdfAsync(exportProperties); + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BNhyiZZKhzLBWLhu?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Export current view records + +The PDF export functionality allows you to export only the records that are currently visible on the Gantt chart to a PDF document. This can be achieved by enabling the [IsCurrentViewExport](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfExportEventArgs.html#Syncfusion_Blazor_Gantt_PdfExportEventArgs_IsCurrentViewExport) boolean property in the [PdfExporting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfExporting) event. + +> Exporting current view records is only applicable when the virtualization feature is enabled, and it does not retain the state of collapsed rows during export. + +The following code demonstrates how to use the `PdfExporting` event to export the current view data of the Gantt chart to a PDF document: + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Navigations + + + + + + + + + + + + + + + + + + + + +@code { + private SfGantt Gantt { get; set; } + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + private List TaskCollection { get; set; } + protected override void OnInitialized() + { + this.TaskCollection = VirtualData.GetTreeVirtualData(30); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + await Gantt.ExportToPdfAsync(); + } + } + public void PdfExportingHandler(PdfExportEventArgs args) + { + args.IsCurrentViewExport = true; + } + public class VirtualData + { + public static List GetTreeVirtualData(int count) + { + List DataCollection = new List(); + Random rand = new Random(); + var x = 0; + int duration = 0; + DateTime startDate = new DateTime(2000, 1, 5); + DateTime endDate = new DateTime(2000, 1, 12); + string[] assignee = { "Allison Janney", "Bryan Fogel", "Richard King", "Alex Gibson" }; + string[] reporter = { "James Ivory", "Jordan Peele", "Guillermo del Toro", "Gary Oldman" }; + for (var i = 1; i <= count / 5; i++) + { + var name = rand.Next(0, 100); + TaskData Parent = new TaskData() + { + ID = ++x, + TaskName = "Task " + x, + StartDate = startDate, + EndDate = startDate.AddDays(26), + Duration = "20", + Assignee = "Mark Bridges", + Reporter = "Kobe Bryant", + Progress = 50, + }; + DataCollection.Add(Parent); + for (var j = 1; j <= 4; j++) + { + startDate = startDate.AddDays(j == 1 ? 0 : duration + 2); + duration = 5; + DataCollection.Add(new TaskData() + { + ID = ++x, + TaskName = "Task " + x, + StartDate = startDate, + EndDate = startDate.AddDays(5), + Duration = duration.ToString(), + Assignee = assignee[j - 1], + Reporter = reporter[j - 1], + Progress = 50, + ParentID = Parent.ID, + }); + } + } + return DataCollection; + } + } + public class TaskData + { + public int ID { get; set; } + public string TaskName { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public string Assignee { get; set; } + public string Reporter { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/hjhyWjtqBfpHsisd?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## How to export Gantt chart with custom timeline range + +The PDF export functionality allows you to export a specific timeline range of the Gantt chart to a PDF document. To define the custom range, set the [RangeStart](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfExportEventArgs.html#Syncfusion_Blazor_Gantt_PdfExportEventArgs_RangeStart) and [RangeEnd](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfExportEventArgs.html#Syncfusion_Blazor_Gantt_PdfExportEventArgs_RangeEnd) properties within the [PdfExporting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfExporting) event. + +The `RangeStart` property specifies the start date, and the `RangeEnd` property specifies the end date of the timeline range to be exported. + +The following code demonstrates how to use the `PdfExporting` event to export a custom timeline range of the Gantt chart to a PDF document: + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Navigations + + + + + + + + + + + + + + + + + + + + +@code { + private SfGantt Gantt { get; set; } + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + private List TaskCollection { get; set; } + protected override void OnInitialized() + { + this.TaskCollection = VirtualData.GetTreeVirtualData(30); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + await Gantt.ExportToPdfAsync(); + } + } + public void PdfExportingHandler(PdfExportEventArgs args) + { + args.RangeStart = new DateTime(2000, 1, 14); + args.RangeEnd = new DateTime(2000, 05, 12); + } + public class VirtualData + { + public static List GetTreeVirtualData(int count) + { + List DataCollection = new List(); + var x = 0; + int duration = 0; + DateTime startDate = new DateTime(2000, 1, 5); + DateTime endDate = new DateTime(2000, 1, 12); + string[] assignee = { "Allison Janney", "Bryan Fogel", "Richard King", "Alex Gibson" }; + string[] reporter = { "James Ivory", "Jordan Peele", "Guillermo del Toro", "Gary Oldman" }; + for (var i = 1; i <= count / 5; i++) + { + TaskData Parent = new TaskData() + { + ID = ++x, + TaskName = "Task " + x, + StartDate = startDate, + EndDate = startDate.AddDays(26), + Duration = "20", + Assignee = "Mark Bridges", + Reporter = "Kobe Bryant", + Progress = 50, + }; + DataCollection.Add(Parent); + for (var j = 1; j <= 4; j++) + { + startDate = startDate.AddDays(j == 1 ? 0 : duration + 2); + duration = 5; + DataCollection.Add(new TaskData() + { + ID = ++x, + TaskName = "Task " + x, + StartDate = startDate, + EndDate = startDate.AddDays(5), + Duration = duration.ToString(), + Assignee = assignee[j - 1], + Reporter = reporter[j - 1], + Progress = 50, + ParentID = Parent.ID, + }); + } + } + return DataCollection; + } + } + public class TaskData + { + public int ID { get; set; } + public string TaskName { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public string Assignee { get; set; } + public string Reporter { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/rtByWjjUrpHrtFIB?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Export hidden columns + +PDF export provides an option to export hidden columns of Gantt by defining the [IncludeHiddenColumn](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_IncludeHiddenColumn) to **true**. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Navigations + + + + + + + + + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); + exportProperties.IncludeHiddenColumn = true; + await Gantt.ExportToPdfAsync(exportProperties); + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VtreCNXgVTcKHkcY?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Customize column width in exported PDF document + +To customize column widths in the exported PDF document, set the [Width](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html#Syncfusion_Blazor_Gantt_GanttColumn_Width) property for each column using the [Columns](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html#Syncfusion_Blazor_Gantt_GanttPdfExportProperties_Columns) property of the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Navigations +@using Syncfusion.PdfExport + + + + + + + + + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); + exportProperties.Columns = new List() + { + new GanttColumn(){ Field = "TaskID", HeaderText = "Task Id", Width = "200" }, + new GanttColumn(){ Field = "TaskName", HeaderText = "Task Name", Width = "250"}, + new GanttColumn(){ Field = "StartDate", HeaderText = "Start Date", Width = "150"}, + }; + await Gantt.ExportToPdfAsync(exportProperties); + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/LtBostXgrIjeKZvL?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## How to export Gantt chart with specific columns + +### Through property + +The PDF export functionality enables you to export only specific columns from the Gantt chart, rather than exporting all columns by default. To achieve this, set the [Columns](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html#Syncfusion_Blazor_Gantt_GanttPdfExportProperties_Columns) property of the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. This allows you to tailor the exported PDF to include only the columns that are relevant to your needs. + +The following code snippet demonstrates how to configure the `Columns` property to export specific columns from the Gantt chart to a PDF document: + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Navigations +@using Syncfusion.PdfExport + + + + + + + + + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); + exportProperties.Columns = new List() + { + new GanttColumn(){ Field = "TaskID", HeaderText = "Task Id", Width = "100" }, + new GanttColumn(){ Field = "TaskName", HeaderText = "Task Name", Width = "200"}, + new GanttColumn(){ Field = "StartDate", HeaderText = "Start Date", Width = "150"}, + }; + await Gantt.ExportToPdfAsync(exportProperties); + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/hXhIiXZAVoCQueAU?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +### Through event + +The PDF export functionality allows you to export only specific columns from the Gantt chart, rather than exporting all columns by default. This can be achieved by using the `Columns` argument in the [PdfExporting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfExporting) event. + +The following code demonstrates how to use the `PdfExporting` event to export specific columns of the Gantt chart to a PDF document, + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Navigations +@using Syncfusion.PdfExport + + + + + + + + + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + await Gantt.ExportToPdfAsync(); + } + } + public void PdfExportingHandler(PdfExportEventArgs args) + { + args.Columns = new List() + { + new GanttColumn(){ Field = "TaskID", HeaderText = "Task Id", Width = "100" }, + new GanttColumn(){ Field = "TaskName", HeaderText = "Task Name", Width = "200"}, + new GanttColumn(){ Field = "StartDate", HeaderText = "Start Date", Width = "150"}, + }; + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/hXVoCjXAVSBmCcUQ?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Customizing taskbar appearance + +You can customize the appearance of taskbars in the exported PDF document using either properties or events, based on your requirements. + +### Through property + +The PDF export functionality allows you to customize the appearance of taskbars in the exported PDF document using the [TaskbarColor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfGanttStyle.html#Syncfusion_Blazor_Gantt_PdfGanttStyle_TaskbarColor) property in the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. This property lets you define custom colors for different types of taskbars, including: + +* Parent Taskbars +* Child Taskbars +* Milestones +* Critical Paths +* Manual Taskbars +* Baselines + +The following code snippet demonstrates how to customize taskbar colors in the exported PDF document: + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Navigations +@using Syncfusion.PdfExport + + + + + + + + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + GanttPdfExportProperties pdfExport = new GanttPdfExportProperties(); + pdfExport.Style = new PdfGanttStyle(); + pdfExport.Style.TaskbarColor = new PdfTaskbarColor(); + pdfExport.Style.TaskbarColor.ParentTaskbarColor = new PdfColor(220, 118, 51); + pdfExport.Style.TaskbarColor.ParentProgressColor = new PdfColor(203, 67, 53); + pdfExport.Style.TaskbarColor.ChildProgressColor = new PdfColor(35, 155, 86); + pdfExport.Style.TaskbarColor.ChildTaskbarColor = new PdfColor(130, 224, 170); + pdfExport.Style.TaskbarColor.CriticalPathTaskbarColor = new PdfColor(173, 121, 64); + pdfExport.Style.TaskbarColor.CriticalPathProgressColor = new PdfColor(145, 76, 0); + pdfExport.Style.TaskbarColor.BaselineColor = new PdfColor(179, 38, 30); + pdfExport.Style.TaskbarColor.MilestoneColor = new PdfColor(141, 124, 187); + await Gantt.ExportToPdfAsync(pdfExport); + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime? BaselineStartDate { get; set; } + public DateTime? BaselineEndDate { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 04), StartDate = new DateTime(2021, 04, 02), EndDate = new DateTime(2021, 04, 08) }, + new TaskData() { TaskID = 2, TaskName = "Identify site location", StartDate = new DateTime(2021, 04, 02), EndDate = new DateTime(2021, 04, 02), Duration = "0", BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 02), Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2021, 04, 02), Duration = "5", Progress = 40, BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 06), ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2021, 04, 08), Duration = "0", EndDate = new DateTime(2021, 04, 08), BaselineStartDate = new DateTime(2021, 04, 08), BaselineEndDate = new DateTime(2021, 04, 08), Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project initiation", StartDate = new DateTime(2021, 04, 02), EndDate = new DateTime(2021, 04, 08) }, + new TaskData() { TaskID = 6, TaskName = "Identify site location", StartDate = new DateTime(2021, 04, 02), Duration = "2", Progress = 30, ParentID = 5, BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 02) }, + new TaskData() { TaskID = 7, TaskName = "Perform soil test", StartDate = new DateTime(2021, 04, 02), Duration = "4", Progress = 40, ParentID = 5, BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 03) }, + new TaskData() { TaskID = 8, TaskName = "Soil test approval", StartDate = new DateTime(2021, 04, 02), Duration = "5", Progress = 30, ParentID = 5, BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 04) } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BXVyijDKBofOIgSk?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +### Through event + +The PDF export functionality allows you to customize the appearance of taskbars in the exported PDF document using the [PdfQueryTaskbarInfo](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfQueryTaskbarInfo) event. This event provides flexibility to format various taskbar types, including parent taskbars, individual taskbars, and milestone templates. + +The following code snippet demonstrates how to use the `PdfQueryTaskbarInfo` event to customize taskbar appearance in the exported PDF document: + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Navigations +@using Syncfusion.PdfExport + + + + + + + + + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + await Gantt.ExportToPdfAsync(); + } + } + public void PdfQueryTaskbarInfoHandler(PdfQueryTaskbarInfoEventArgs args) + { + if (args.Data.TaskID == 3) + { + args.TaskbarStyle.Color = new PdfTaskbarColor(); + args.TaskbarStyle.Color.ChildProgressColor = new Syncfusion.PdfExport.PdfColor(103, 80, 164); + args.TaskbarStyle.Color.ChildTaskbarColor = new Syncfusion.PdfExport.PdfColor(141, 124, 187); + } + if (args.Data.TaskID == 4) + { + args.TaskbarStyle.Color = new PdfTaskbarColor(); + args.TaskbarStyle.Color.MilestoneColor = new Syncfusion.PdfExport.PdfColor(103, 80, 164); + } + + } + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VDheittqhyxNSXIj?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Exporting with templates + +### Exporting with column template + +The PDF export functionality allows for advanced customization of Gantt chart columns, including the inclusion of images, background colors, and custom text. This can be achieved using the [PdfQueryCellInfo](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfQueryCellInfo) event. By handling this event, you can define how individual cells in the Gantt chart are rendered in the exported PDF. + +The following code snippet demonstrates how to use the `PdfQueryCellInfo` event to export Gantt columns with custom text and different cell background colors, + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Navigations +@using Syncfusion.PdfExport + + + + + + + + + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + await Gantt.ExportToPdfAsync(); + } + } + public void PdfQueryCellInfoHandler(Syncfusion.Blazor.Gantt.PdfQueryCellInfoEventArgs args) + { + if (args.Column.Field == "TaskName" && args.Data.TaskID == 5) + { + args.Cell.Value = "Updated Value"; + args.Cell.CellStyle = new PdfElementStyle() + { + FillBackgroundColor = "Orange", + Font = new PdfGridFont() + { + FontFamily = PdfFontFamily.TimesRoman, + FontSize = 6, + FontStyle = PdfFontStyle.Italic, + IsTrueType = false, + TextColor = "Red", + TextHighlightColor = "Green" + } + }; + args.Cell.CellStyle.Border = new Syncfusion.Blazor.Grids.PdfBorder() + { + Color = "Black", + DashStyle = Syncfusion.Blazor.Grids.PdfDashStyle.Dot, + Width = 0.1 + }; + } + } + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VDLejELSpVTlPVsF?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +### Exporting with column header template + +The PDF export functionality allows to export header template that include `images` and `text` to an PDF document using [PdfColumnHeaderQueryCellInfo](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfColumnHeaderQueryCellInfo) event. + +In the following sample, header template with images and text are exported to PDF using [HeaderTemplate](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html#Syncfusion_Blazor_Gantt_GanttColumn_HeaderTemplate) properties in the `PdfColumnHeaderQueryCellInfo` event. + +> PDF Export supports base64 string to export the images. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.PdfExport +@using System.Net.Http +@using System.IO +@inject HttpClient Http + + + + + + +
    + + @((context as GridColumn).HeaderText) +
    +
    +
    + + +
    + + @((context as GridColumn).HeaderText) +
    +
    +
    +
    + +
    +@code{ + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { + new Syncfusion.Blazor.Navigations.ToolbarItem() { + Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" + } + }; + + public PdfImage image; + protected override async Task OnInitializedAsync() + { + TaskCollection = GetTaskCollection(); + var imageBytes = await Http.GetByteArrayAsync("https://cdn.syncfusion.com/content/images/landing-page/yes.png"); + using var imageStream = new MemoryStream(imageBytes); + image = PdfImage.FromStream(imageStream); + } + + + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + await Gantt.ExportToPdfAsync(); + } + } + + public void PdfHeaderQueryCellInfoHandler(Syncfusion.Blazor.Gantt.PdfHeaderQueryCellInfoEventArgs args) + { + args.Cell.CellStyle = new PdfElementStyle(){ Image = image }; + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? Parent_Id { get; set; } + + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21)}, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Parent_Id = 1}, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Parent_Id = 1}, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Parent_Id =1}, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21)}, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Parent_Id =5}, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Parent_Id =5}, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Parent_Id =5} + + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VtresXgMqlBQjXfl?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +### Exporting with task label template + +The PDF export functionality allows to export task label template that include `images` and `text` to an PDF document using [PdfQueryTaskbarInfo](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfQueryTaskbarInfo) event. + +In the following sample, task label template with images and text are exported to PDF using [LabelSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfQueryTaskbarInfoEventArgs-1.html#Syncfusion_Blazor_Gantt_PdfQueryTaskbarInfoEventArgs_1_LabelSettings) properties in the [PdfQueryTaskbarInfoEventArgs](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfQueryTaskbarInfoEventArgs-1.html) event. + +> PDF Export supports base64 string to export the images. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Navigations +@using Syncfusion.PdfExport +@using System.Net.Http +@using System.IO + + + + + + + + + + + + + + + @{ + if ((context as TaskData).TaskID == 5) + { +
    + + @((context as TaskData).TaskName) +
    + } + } +
    + + @if ((context as TaskData).TaskID == 2) + { +
    + Updated Value +
    + } + else + { +
    + @((context as TaskData).TaskName) +
    + } +
    + + @if ((context as TaskData).TaskID == 3) + { +
    + -@((context as TaskData).Progress)% +
    + } + else + { +
    + @((context as TaskData).Progress)% +
    + } +
    +
    + +
    + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() + { + new Syncfusion.Blazor.Navigations.ToolbarItem() + { + Text = "PDF Export", + TooltipText = "PDF Export", + Id = "PdfExport", + PrefixIcon = "e-pdfexport" + } + }; + + public static PdfImage image; + + protected override async Task OnInitializedAsync() + { + this.TaskCollection = GetTaskCollection(); + + using var httpClient = new HttpClient(); + var imageBytes = await httpClient.GetByteArrayAsync("https://cdn.syncfusion.com/content/images/landing-page/yes.png"); + var imageStream = new MemoryStream(imageBytes); + image = PdfImage.FromStream(imageStream); + } + + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + await Gantt.ExportToPdfAsync(); + } + } + + public void PdfQueryTaskbarInfoHandler(PdfQueryTaskbarInfoEventArgs args) + { + if (args.Data.TaskID == 2) + { + args.LabelSettings.LeftLabelValue = "Updated Value"; + } + else + { + args.LabelSettings.LeftLabelValue = args.Data.TaskName; + } + + if (args.Data.TaskID == 5) + { + args.LabelSettings.RightLabel = new PdfElementStyle() { Image = image }; + } + else + { + args.LabelSettings.RightLabelValue = args.Data.TaskName; + } + + if (args.Data.TaskID == 3) + { + args.LabelSettings.TaskbarLabelValue = $"-{args.Data.Progress}%"; + } + else + { + args.LabelSettings.TaskbarLabelValue = $"{args.Data.Progress}%"; + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + return new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21) }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21) }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/LtLyNOhefKeOHrhh?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +### Best practices for exporting PDF with templates + +- **Optimize PdfQueryCellInfo event usage**: Use the `PdfQueryCellInfo` event to customize individual cell appearances efficiently. Minimize complex logic to maintain performance. + +- **Utilize PdfColumnHeaderQueryCellInfo effectively**: Apply the `PdfColumnHeaderQueryCellInfo` event for custom header styles and content, focusing on clarity and readability. +- **Accessibility and clarity**: Keep header elements simple and accessible. Use straightforward text and icons to convey column purposes clearly. + +- **Efficient use of PdfQueryTaskbarInfo**: Utilize the `PdfQueryTaskbarInfo` event to apply label customizations based on task data conditions for effective communication of task statuses. +- **Consistent label styling**: Ensure consistent theme across labels with uniform font styles, colors, and sizes. + +### Image handling across events +- **Base64 and MemoryStream**: Convert images to Base64 strings, then use `MemoryStream` to convert them to `PdfImage`. This avoids reliance on potentially inaccessible web links. +- **Height and width management**: Scale images to fit designated areas to prevent default resizing that reflects cell or row heights. Maintain a professional PDF layout. +- **Compression and optimization**: Compress images prior to Base64 conversion to reduce file size while maintaining quality, optimizing the final PDF document size. + +### Troubleshooting PDF export + +1. **Customizations not appearing in PDF** + - **Check event handler**: Ensure that the `PdfQueryTaskbarInfo` event is correctly implemented and bound in your code. Double-check the event handler's logic to verify that conditions for customization are being met. + - **Data matching**: Ensure that the task data (like `TaskID`) used in the event matches the data in the task collection. Mismatches can prevent customizations from applying. + +2. **Images not displaying** + - **Image URL**: Verify that the image URLs are correct and accessible. Ensure that external images are hosted on a server with public access rights. + - **Supported formats**: Use compatible image formats such as JPG, PNG, or GIF. Unsupported formats may not render correctly in a PDF. + +3. **Performance issues** + - **Optimize resources**: Large images or complex styling may slow down the PDF export process. Consider optimizing image size and simplifying styles. + +4. **Color code customization** + - **Use valid color codes**: You can use HEX (`#RRGGBB`), or standard color names like `red`, `blue`, etc. Ensure all color codes or names used are supported and valid. + - **Consistency across styles**: Maintain consistent use of color codes in the styles to avoid unexpected color changes or conflicts during PDF rendering. \ No newline at end of file diff --git a/blazor/gantt-chart/data-markers.md b/blazor/gantt-chart/data-markers.md index cd2f1e074d..7d342143c0 100644 --- a/blazor/gantt-chart/data-markers.md +++ b/blazor/gantt-chart/data-markers.md @@ -9,18 +9,30 @@ documentation: ug # Data Markers in Blazor Gantt Chart Component -[Data markers](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttIndicator.html) are a set of events used to represent the schedule events for a task. Data markers are defined in data source as array of objects, and this value is mapped to the Gantt Chart component using the `GanttTaskFields.Indicators` property. You can represent more than one data marker in a task. +Data markers are visual indicators that highlight significant events, milestones, or important dates within individual project tasks. These markers provide immediate visual context about critical moments in task timelines, enabling effective identification of key dates and tracking of important events at the task level. Understanding data markers implementation ensures effective project visualization and milestone tracking throughout project development cycles. -Data markers can be defined using the following properties: +Data markers utilize specific properties to define their appearance, positioning, and interactive behavior within task timelines: -* `Date` : Defines the date of indicator. -* `IconClass` : Defines the icon class of indicator. -* `Name` : Defines the name of indicator. -* `Tooltip` : Defines the tooltip of indicator. +**Date specification**: The [Date](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttIndicator.html#Syncfusion_Blazor_Gantt_GanttIndicator_Date) property establishes the exact timeline position where the marker appears. This date value determines marker placement relative to the task's start and end dates, ensuring accurate event representation. -N> Data Marker `Tooltip` will be rendered only if tooltip property has value. +**Visual styling**: The [IconClass](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttIndicator.html#Syncfusion_Blazor_Gantt_GanttIndicator_IconClass) property defines the CSS class that controls marker visual appearance. This property enables custom styling through icon fonts, background images, or CSS-based graphics to distinguish different marker types. -The following code example demonstrates how to implement data markers in the Gantt chart. +**Identification**: The [Name](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttIndicator.html#Syncfusion_Blazor_Gantt_GanttIndicator_Name) property provides unique identification for each marker. This name serves as an internal reference and can be used for programmatic marker manipulation or event handling. + +**Interactive content**: The [Tooltip](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttIndicator.html#Syncfusion_Blazor_Gantt_GanttIndicator_Tooltip) property supplies descriptive text that displays when users hover over markers. This property enhances user experience by providing detailed context about marker significance and related event information. + +**Tooltip Rendering Requirements**: Data marker tooltips render only when the tooltip property contains valid content values. Empty or undefined tooltip properties result in no tooltip display, maintaining clean visual presentation for markers without additional descriptions. + +## Data mapping and configuration properties + +Data markers represent schedule events for specific tasks through visual indicators positioned at designated dates within task timelines. The component renders markers as icon-based elements that display at precise timeline locations, providing instant visual reference for important task-related events. + +**Data structure requirements**: Data markers are defined in the data source as arrays of objects containing marker specifications. Each marker object includes date information, visual styling, identification details, and optional tooltip content for enhanced user interaction. + +**Mapping configuration**: The marker array connects to the Gantt component through the [GanttTaskFields.Indicators](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Indicators) property mapping. This configuration establishes the relationship between data source marker definitions and component rendering logic. + +**Multiple marker support**: Tasks can display multiple data markers simultaneously, allowing comprehensive event tracking within individual task contexts. Each marker maintains independent configuration while sharing the same task timeline space. +The following implementation demonstrates comprehensive data marker integration within a Gantt chart, showcasing multiple markers per task with varied styling and tooltip configurations: {% tabs %} {% highlight razor tabtitle="Index.razor" %} diff --git a/blazor/gantt-chart/deleting-tasks.md b/blazor/gantt-chart/deleting-tasks.md index 02c2dee7e0..cc115c69af 100644 --- a/blazor/gantt-chart/deleting-tasks.md +++ b/blazor/gantt-chart/deleting-tasks.md @@ -1,17 +1,19 @@ --- layout: post title: Deleting tasks in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Deleting tasks in Syncfusion Blazor Gantt Chart component and more. +description: Learn how to delete tasks dynamically in the Syncfusion Blazor Gantt Chart component using toolbar or programmatic methods for efficient project management. platform: Blazor -control: Gantt Chart +control: Deleting tasks documentation: ug --- # Deleting Tasks in Blazor Gantt Chart Component -## Deleting Tasks +Deleting tasks in the Blazor Gantt Chart component streamlines project management by removing tasks, such as outdated milestones or subtasks, using the toolbar or programmatic methods. Enabled by setting the [GanttEditSettings.AllowDeleting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowDeleting) property to **true** and tasks can be deleted after selecting a row, ensuring seamless updates to dependencies and critical path calculations. A confirmation dialog, activated via [GanttEditSettings.ShowDeleteConfirmDialog](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_ShowDeleteConfirmDialog), prompts to verify deletions, preventing accidental removals. The [DeleteRecordAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_DeleteRecordAsync_System_Nullable_System_Int32__) method allows programmatic deletion, requiring a selected record with valid `GanttTaskFields` mappings (e.g., id, name). Ensure tasks are selected and `GanttTaskFields` are properly configured to avoid issues during deletion. -A task delete option in the Gantt Chart component can be enabled by enabling the [GanttEditSettings.AllowDeleting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowDeleting) property. Tasks can be deleted by clicking the delete toolbar item or using the `[DeleteRecordAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_DeleteRecordAsync_System_Nullable_System_Int32__) method. You can call this method dynamically on any custom actions like button click. The following code example shows how to enable the delete option in the Gantt Chart component. +## Delete tasks via toolbar + +Enable task deletion through the toolbar by setting [GanttEditSettings.AllowDeleting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowDeleting) to **true**. Select a row and click the toolbar’s **Delete** icon to remove the task, with an optional confirmation dialog if [GanttEditSettings.ShowDeleteConfirmDialog](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_ShowDeleteConfirmDialog) is enabled. This method is ideal for quickly removing tasks like completed activities. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -73,11 +75,9 @@ A task delete option in the Gantt Chart component can be enabled by enabling the N> You should set the `AllowDeleting` value to `true` to delete the record dynamically. -## Delete confirmation message - -Delete confirmation message is used to get confirmation from users before deleting a task. This confirmation message can be enabled by setting the [GanttEditSettings.ShowDeleteConfirmDialog](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_ShowDeleteConfirmDialog) property to true. +## Delete tasks with confirmation dialog -The following code snippet explains how to enable the delete confirmation message in Gantt Chart. +Enable a confirmation dialog for task deletion by setting [GanttEditSettings.ShowDeleteConfirmDialog](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_ShowDeleteConfirmDialog) to **true**, alongside [GanttEditSettings.AllowDeleting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowDeleting) . After selecting a row, deleting via the toolbar or [DeleteRecordAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_DeleteRecordAsync_System_Nullable_System_Int32__) method prompts a dialog to confirm the action, ensuring intentional removals. This is useful for critical tasks where accidental deletion must be avoided. {% tabs %} {% highlight razor tabtitle="Index.razor" %} diff --git a/blazor/gantt-chart/editing-tasks.md b/blazor/gantt-chart/editing-tasks.md index 047ec69f5b..64d9fc1dd9 100644 --- a/blazor/gantt-chart/editing-tasks.md +++ b/blazor/gantt-chart/editing-tasks.md @@ -1,33 +1,28 @@ --- layout: post title: Editing tasks in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Editing tasks in Syncfusion Blazor Gantt Chart component and more. +description: Learn to dynamically edit tasks in Syncfusion Blazor Gantt Chart using cell, dialog, taskbar, or code-based methods for seamless project updates. platform: Blazor -control: Gantt Chart +control: Editing tasks documentation: ug --- # Editing tasks in Blazor Gantt Chart Component -The editing feature can be enabled in the Gantt Chart component by enabling the [GanttEditSettings.AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowEditing) and [GanttEditSettings.AllowTaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowTaskbarEditing) properties. +Editing tasks in the Blazor Gantt Chart component enables dynamic project updates, such as modifying task durations, names, or dependencies, using cell editing, dialog, taskbar interactions, or programmatic methods. Enable editing by setting [GanttEditSettings.AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowEditing) and [GanttEditSettings.AllowTaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowTaskbarEditing) to **true**, ensuring task data aligns with [TaskFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html) mappings (e.g., id, name, startDate). Cell editing allows direct updates in the TreeGrid pane, dialog editing provides a comprehensive interface, taskbar dragging adjusts durations or dates, and connector lines manage dependencies via drag-and-drop. Use the [GanttEditSettings.Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_Mode) property to control editing behavior (**Auto** or **Dialog**). Customize dialog fields with [AddDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAddDialogFields.html#Syncfusion_Blazor_Gantt_GanttAddDialogFields_AddDialogFields) and [EditDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditDialogFields.html#Syncfusion_Blazor_Gantt_GanttEditDialogFields_EditDialogFields) for tailored forms. The [UpdateRecordByIDAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_UpdateRecordByIDAsync__0_) method enables programmatic updates, except for task IDs. Ensure valid data to prevent issues and maintain dependency integrity. -The following editing options are available to update the tasks in the Gantt chart: -* Cell -* Dialog -* Taskbar +## Edit tasks via cell editing -## Cell editing +Enable cell editing by setting [GanttEditSettings.AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowEditing) to **true**, [GanttEditSettings.Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_Mode) to **Auto**. Double-click a TreeGrid cell to edit fields like task name or duration directly, ideal for quick updates. Ensure `GanttTaskFields` mappings are valid for seamless editing. -By setting the edit mode to auto using the [GanttEditSettings.Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_Mode) property, the tasks can be edited by double-clicking the Tree Grid cells. +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -The following code example shows you how to enable the cell editing in Gantt Chart component. - -```cshtml @using Syncfusion.Blazor.Gantt - + - + @code{ @@ -39,49 +34,49 @@ The following code example shows you how to enable the cell editing in Gantt Cha public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentId = 5 } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } }; return Tasks; } } -``` -N> When the edit mode is set to `Auto`, double-clicking on the Tree Grid side changes the cells to editable mode. Double-clicking on the chart side opens the edit dialog for editing the task details. +{% endhighlight %} +{% endtabs %} -double click action on Tree Grid or chart side +{% previewsample "https://blazorplayground.syncfusion.com/embed/hNBeCNiDVodpLcuW?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -![Blazor Gantt Chart displays Editing in Chart](images/blazor-gantt-chart-editing-in-chart.png) +N> When the edit mode is set to `Auto`, double-clicking on the Tree Grid side changes the cells to editable mode. Double-clicking on the chart side opens the edit dialog for editing the task details. -{% previewsample "https://blazorplayground.syncfusion.com/embed/VZrKZcibioUFqasP?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} +## Edit tasks via dialog -## Dialog editing +Enable dialog editing by setting [GanttEditSettings.AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowEditing) to **true** and [GanttEditSettings.Mode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_Mode) to **Dialog**. Double-click a row on the TreeGrid or chart side to open a dialog for editing task details, such as start date or dependencies, suitable for comprehensive updates. In **Auto** mode, double-clicking the chart side opens the dialog, while the TreeGrid side enables cell editing. -Modify the task details through the edit dialog by setting the `GanttEditSettings.Mode` as `Dialog`. +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -95,50 +90,54 @@ Modify the task details through the edit dialog by setting the `GanttEditSetting public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentId = 5 } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } }; return Tasks; } } -``` + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/LNBeMDWXLyuhTais?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} N> In dialog editing mode, the edit dialog appears when the Tree Grid or Gantt chart sides are double-clicked. -![Dialog Editing in Blazor Gantt Chart](images/blazor-gantt-chart-dialog-editing.png) +## Sections or tabs in Dialog -### Sections or tabs in Dialog +Customize the edit dialog by defining tabs with [GanttAddDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAddDialogFields.html) and [GanttEditDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditDialogFields.html), using the [GanttAddDialogField.Type](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAddDialogField.html#Syncfusion_Blazor_Gantt_GanttAddDialogField_Type) and [GanttEditDialogField.Type](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditDialogField.html#Syncfusion_Blazor_Gantt_GanttEditDialogField_Type) property (e.g., General, Dependency). This organizes fields into tabs for focused editing, such as task details or dependencies. -In the Gantt Chart dialog, you can define the required tabs or editing sections using the [GanttAddDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAddDialogFields.html) and [GanttEditDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditDialogFields.html) properties. Every tab is defined using the `GanttAddDialogField.Type` or `GanttEditDialogField.Type` property. +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml - @using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Gantt - - + @@ -168,13 +167,13 @@ In the Gantt Chart dialog, you can define the required tabs or editing sections public class TaskInfoModel { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } public string Notes { get; set; } public string Predecessor { get; set; } } @@ -186,8 +185,8 @@ In the Gantt Chart dialog, you can define the required tabs or editing sections public class AssignmentModel { public int PrimaryId { get; set; } - public int TaskId { get; set; } - public int ResourceId { get; set; } + public int TaskID { get; set; } + public int ResourceID { get; set; } } public static List GetResourceCollections() @@ -206,12 +205,12 @@ In the Gantt Chart dialog, you can define the required tabs or editing sections { List assignments = new List() { - new AssignmentModel(){ PrimaryId=1, TaskId = 2, ResourceId=1}, - new AssignmentModel(){ PrimaryId=2, TaskId = 3, ResourceId=2}, - new AssignmentModel(){ PrimaryId=3, TaskId = 3, ResourceId=3}, - new AssignmentModel(){ PrimaryId=4, TaskId = 6, ResourceId=4}, - new AssignmentModel(){ PrimaryId=5, TaskId = 8, ResourceId=1}, - new AssignmentModel(){ PrimaryId=6, TaskId = 8, ResourceId=5} + new AssignmentModel(){ PrimaryId=1, TaskID = 2, ResourceID=1}, + new AssignmentModel(){ PrimaryId=2, TaskID = 3, ResourceID=2}, + new AssignmentModel(){ PrimaryId=3, TaskID = 3, ResourceID=3}, + new AssignmentModel(){ PrimaryId=4, TaskID = 6, ResourceID=4}, + new AssignmentModel(){ PrimaryId=5, TaskID = 8, ResourceID=1}, + new AssignmentModel(){ PrimaryId=6, TaskID = 8, ResourceID=5} }; return assignments; } @@ -220,43 +219,43 @@ In the Gantt Chart dialog, you can define the required tabs or editing sections { List Tasks = new List() { - new TaskInfoModel() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskInfoModel() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Notes = "Measure the total property area alloted for construction", ParentId = 1 }, - new TaskInfoModel() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Predecessor = "2", Notes = "Obtain an engineered soil test of a plot where construction is planned from an engineer or company specializing in soil testing", ParentId = 1 }, - new TaskInfoModel() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentId = 1 }, - new TaskInfoModel() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskInfoModel() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", Notes = "Develop floor plans and obtain a materials list for estimations", ParentId = 5 }, - new TaskInfoModel() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Predecessor = "6", Notes = "", ParentId = 5 }, - new TaskInfoModel() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Predecessor = "7", Notes = "", ParentId = 5 } + new TaskInfoModel() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskInfoModel() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Notes = "Measure the total property area alloted for construction", ParentID = 1 }, + new TaskInfoModel() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Predecessor = "2", Notes = "Obtain an engineered soil test of a plot where construction is planned from an engineer or company specializing in soil testing", ParentID = 1 }, + new TaskInfoModel() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentID = 1 }, + new TaskInfoModel() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 11), EndDate = new DateTime(2022, 04, 18), }, + new TaskInfoModel() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 11), Duration = "3", Progress = 30, Predecessor = "4", Notes = "Develop floor plans and obtain a materials list for estimations", ParentID = 5 }, + new TaskInfoModel() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 14), Duration = "3", Predecessor = "6", Notes = "", ParentID = 5 }, + new TaskInfoModel() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 18), Duration = "0", Predecessor = "7", Notes = "", ParentID = 5 } }; return Tasks; } } -``` -Tabs in Edit or Add Dialog +{% endhighlight %} +{% endtabs %} -![Adding New DialogTabs in Blazor Gantt Chart](images/blazor-gantt-chart-add-dialogtab.png) +{% previewsample "https://blazorplayground.syncfusion.com/embed/rNVSWZiDBQDQDzvd?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - +### Limit fields in general tab -### Limiting data fields in general tab +Restrict fields in the dialog’s General tab using [GanttAddDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAddDialogFields.html) and [GanttEditDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditDialogFields.html) with the [GanttAddDialogField.Type](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAddDialogField.html#Syncfusion_Blazor_Gantt_GanttAddDialogField_Type) and [GanttEditDialogField.Type](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditDialogField.html#Syncfusion_Blazor_Gantt_GanttEditDialogField_Type) properties set to **General** and [Fields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditDialogField.html#Syncfusion_Blazor_Gantt_GanttEditDialogField_Fields) specifying visible fields (e.g., TaskName, Duration). This streamlines editing by showing only relevant fields. -In the Gantt Chart dialog, you can make only specific data source fields visible for editing by using the `GanttAddDialogFields` and `GanttEditDialogFields` properties. The data fields are defined with `GanttEditDialogField.Type` and `GanttEditDialogField.Fields` properties. +> You can also define the custom fields in the add/edit dialog General tab using the `Fields` property. -`Note:` You can also define the custom fields in the add/edit dialog General tab using the `Fields` property. +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml - @using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Gantt - - + @@ -264,12 +263,12 @@ In the Gantt Chart dialog, you can make only specific data source fields visible + Fields="@(new string[]{ "TaskID", "TaskName", "Duration" })"> + Fields="@(new string[]{ "TaskID", "TaskName", "Duration" })"> @@ -283,13 +282,13 @@ In the Gantt Chart dialog, you can make only specific data source fields visible public class TaskInfoModel { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } public string Notes { get; set; } public string Predecessor { get; set; } } @@ -298,40 +297,46 @@ In the Gantt Chart dialog, you can make only specific data source fields visible { List Tasks = new List() { - new TaskInfoModel() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskInfoModel() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Notes = "Measure the total property area alloted for construction", ParentId = 1 }, - new TaskInfoModel() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Predecessor = "2", Notes = "Obtain an engineered soil test of a plot where construction is planned from an engineer or company specializing in soil testing", ParentId = 1 }, - new TaskInfoModel() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentId = 1 }, - new TaskInfoModel() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskInfoModel() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", Notes = "Develop floor plans and obtain a materials list for estimations", ParentId = 5 }, - new TaskInfoModel() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Predecessor = "6", Notes = "", ParentId = 5 }, - new TaskInfoModel() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Predecessor = "7", Notes = "", ParentId = 5 } + new TaskInfoModel() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskInfoModel() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Notes = "Measure the total property area alloted for construction", ParentID = 1 }, + new TaskInfoModel() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Predecessor = "2", Notes = "Obtain an engineered soil test of a plot where construction is planned from an engineer or company specializing in soil testing", ParentID = 1 }, + new TaskInfoModel() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentID = 1 }, + new TaskInfoModel() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 11), EndDate = new DateTime(2022, 04, 18), }, + new TaskInfoModel() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", Notes = "Develop floor plans and obtain a materials list for estimations", ParentID = 5 }, + new TaskInfoModel() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Predecessor = "6", Notes = "", ParentID = 5 }, + new TaskInfoModel() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Predecessor = "7", Notes = "", ParentID = 5 } }; return Tasks; } } -``` -The following screenshot show the output of above code example. +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/LNLSWXiyWEIoOWHT?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Edit task dependencies -![Blazor Gantt Chart with Custom Fields](images/blazor-gantt-chart-custom-fields.png) +Enable dependency editing by mapping the [GanttTaskFields.Dependency](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Dependency) property in `GanttTaskFields`, setting [GanttEditSettings.AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowEditing) and [GanttEditSettings.AllowTaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowTaskbarEditing) to **true**. Update dependencies via: +- **Mouse interactions**: Drag connector points on taskbars to create or modify links. -## Task dependencies + ![Updating task dependency with mouse drag and drop action](images/user-interaction.png) -In the Gantt Chart component, you can update the dependencies between tasks and link the tasks interactively. The task dependencies can be mapped from the data source using the [GanttTaskFields.Dependency](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Dependency) property. +- **Dialog**: Edit the Dependency tab in the edit dialog. -You can update the task dependencies using the following ways: + ![Updating task dependency in dialog Dependency tab](images/editing-dialog.png) -* Edit dialog: Create or remove the task dependencies using the `Dependency` tab in the edit dialog. -* Cell editing: Create or remove the task links using cell editing. +- **Cell editing**: Update the dependency field in the TreeGrid. Ensure valid dependency strings to avoid circular references. -The following code example demonstrates how to enable task dependency editing in the Gantt chart using the `EditSettings` property. + ![Updating task dependency via cell editing in TreeGrid](images/cell-edit.png) + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -345,49 +350,49 @@ The following code example demonstrates how to enable task dependency editing in public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } public string Predecessor { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List(); - Tasks.Add(new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }); - Tasks.Add(new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }); - Tasks.Add(new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentId = 1 }); - Tasks.Add(new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentId = 1 }); - Tasks.Add(new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }); - Tasks.Add(new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentId = 5 }); - Tasks.Add(new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentId = 5 }); - Tasks.Add(new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentId = 5 }); + Tasks.Add(new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }); + Tasks.Add(new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }); + Tasks.Add(new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentID = 1 }); + Tasks.Add(new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentID = 1 }); + Tasks.Add(new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 11), EndDate = new DateTime(2022, 04, 18), }); + Tasks.Add(new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentID = 5 }); + Tasks.Add(new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentID = 5 }); + Tasks.Add(new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentID = 5 }); return Tasks; } } -``` -Updating with cell Edit or Dialog +{% endhighlight %} +{% endtabs %} -![Dialog Editing in Blazor Gantt Chart](images/blazor-gantt-chart-edit-dialog.png) +{% previewsample "https://blazorplayground.syncfusion.com/embed/LXBIWDWeiYcZSwrs?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - +## Edit tasks programmatically -## Update task values using method +Update tasks programmatically using the [UpdateRecordByIDAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_UpdateRecordByIDAsync__0_) method, specifying the task ID and updated data. This method supports automation, such as updating durations via a button, but cannot modify the task ID. Ensure `GanttTaskFields` mappings are valid for successful updates. -Tasks' value can be dynamically updated by using the [UpdateRecordByIDAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_UpdateRecordByIDAsync__0_) method. You can call this method on any custom action. The following code example shows how to use this method to update a task. +> Using the `UpdateRecordByIDAsync` method, you cannot update the task ID value. -N> Using the `UpdateRecordByIDAsync` method, you cannot update the task ID value. +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -396,7 +401,7 @@ N> Using the `UpdateRecordByIDAsync` method, you cannot update the task ID value public SfGantt Gantt; public void UpdateRecord() { - this.Gantt.UpdateRecordByIDAsync(new TaskData() { TaskId = 3, TaskName = "Updated by ID value", Progress = 60}); + this.Gantt.UpdateRecordByIDAsync(new TaskData() { TaskID = 3, TaskName = "Updated by ID value", Progress = 60}); } private List TaskCollection { get; set; } protected override void OnInitialized() @@ -406,30 +411,37 @@ N> Using the `UpdateRecordByIDAsync` method, you cannot update the task ID value public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentId = 5 } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } }; return Tasks; } } -``` -![Updating Record in Blazor Gantt Chart](images/blazor-gantt-chart-update-record.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BjBoiXWysOvZYpeG?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## See also +- [How to add new tasks?](https://blazor.syncfusion.com/documentation/gantt-chart/adding-new-tasks) +- [How to manage task dependencies?](https://blazor.syncfusion.com/documentation/gantt-chart/task-dependencies) +- [How to configure critical path?](https://blazor.syncfusion.com/documentation/gantt-chart/criticalpath) \ No newline at end of file diff --git a/blazor/gantt-chart/event-markers.md b/blazor/gantt-chart/event-markers.md index a56aa9c057..1a274bdf67 100644 --- a/blazor/gantt-chart/event-markers.md +++ b/blazor/gantt-chart/event-markers.md @@ -3,7 +3,7 @@ layout: post title: Event Markers in Blazor Gantt Chart Component | Syncfusion description: Checkout and learn here all about Event Markers in Syncfusion Blazor Gantt Chart component and more. platform: Blazor -control: Gantt Chart +control: Eventmarkers documentation: ug --- @@ -11,11 +11,35 @@ documentation: ug The event markers in the Gantt Chart component is used to highlight the important events in a project. Event markers can be initialized by using the [GanttEventMarkers](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEventMarkers.html) property, and you can define date and label for the event markers using the `Day` and `Label` properties. You can also customize it using the `CssClass` properties. The following code example shows how to add event markers in the Gantt Chart component. -```cshtml +Event markers highlight significant project events by displaying vertical timeline indicators that span across the entire Gantt chart. These markers identify critical dates, milestones, deadlines, or important project events that affect multiple tasks or the overall project timeline, providing visual reference points for project-wide activities. + +Understanding event markers implementation enables effective visualization of project-critical dates and enhances timeline awareness across all project phases. + +Event markers utilize specific properties to define their positioning, appearance, and identification within the project timeline: + +**Date positioning**: The [Day](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEventMarker.html#Syncfusion_Blazor_Gantt_GanttEventMarker_Day) property establishes the exact timeline date where the marker appears. This date value determines marker placement across the entire vertical timeline, ensuring accurate project event representation. + +**Descriptive labeling**: The [Label](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEventMarker.html#Syncfusion_Blazor_Gantt_GanttEventMarker_Label) property provides descriptive text that identifies the marker's purpose or significance. Labels enhance user understanding by clearly indicating what project event the marker represents. + +**Visual customization**: The [CssClass](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEventMarker.html#Syncfusion_Blazor_Gantt_GanttEventMarker_CssClass) property enables custom styling through CSS class applications. This property allows distinctive visual treatment for different marker types, supporting color coding, styling variations, and brand consistency. + +## Event marker configuration + +Event markers render as vertical lines positioned at specific dates across the entire Gantt timeline, distinguishing them from data markers which appear within individual task rows. This project-wide visibility ensures critical dates remain prominent regardless of the current view or task focus. + +**Timeline integration**: Event markers integrate seamlessly with the Gantt timeline, appearing as vertical indicators that extend from the top to the bottom of the chart area. This comprehensive visibility ensures important dates remain visible during scrolling, zooming, or filtering operations. + +**Multiple marker support**: The component supports multiple event markers simultaneously, allowing comprehensive tracking of various project-critical dates within the same timeline view. Each marker maintains independent configuration while sharing the common timeline space. + +The following implementation demonstrates event marker integration within a Gantt chart, showcasing timeline-wide event highlighting: + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + @using Syncfusion.Blazor.Gantt - + GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentId = 5 } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } }; return Tasks; } @@ -64,13 +88,14 @@ The event markers in the Gantt Chart component is used to highlight the importan border-left: 2px red dotted; } -``` -![Blazor Gantt Chart with Event Markers](images/blazor-gantt-chart-event-markers.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BNVoiXhJTzbnRpdT?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## See also * [Display Striplines in Blazor Gantt](https://www.syncfusion.com/forums/175385/display-striplines-in-blazor-gantt) - -N> You can refer to our [Blazor Gantt Chart](https://www.syncfusion.com/blazor-components/blazor-gantt-chart) feature tour page for its groundbreaking feature representations. You can also explore our [Blazor Gantt Chart example](https://blazor.syncfusion.com/demos/gantt-chart/default-functionalities?theme=bootstrap5) to know how to render and configure the Gantt. +N> You can refer to our [Blazor Gantt Chart](https://www.syncfusion.com/blazor-components/blazor-gantt-chart) feature tour page for its groundbreaking feature representations. You can also explore our [Blazor Gantt Chart example](https://blazor.syncfusion.com/demos/gantt-chart/default-functionalities?theme=bootstrap5) to know how to render and configure the Gantt. \ No newline at end of file diff --git a/blazor/gantt-chart/header-and-footer.md b/blazor/gantt-chart/header-and-footer.md new file mode 100644 index 0000000000..b03b2c2ae6 --- /dev/null +++ b/blazor/gantt-chart/header-and-footer.md @@ -0,0 +1,206 @@ +--- +layout: post +title: Customizing PDF Headers and Footers in Blazor Gantt Chart Component | Syncfusion +description: Learn how to customize headers and footers in PDF exports of the Syncfusion Blazor Gantt Chart component with text, lines, page numbers, and images. +platform: Blazor +control: header and footer of PDF exporting +documentation: ug +--- + +# Header and footer of PDF exporting in Blazor Gantt Chart component + +Customizing headers and footers in PDF exports of the Blazor Gantt Chart component allows adding text, lines, page numbers, and images to enhance document professionalism for projects. Use [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) with [Header](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Header) and [Footer](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Footer) to define content arrays, specifying `Type` (e.g., Text, Line), `Value`, `Position`, `Style`, or `Src` for images with `Base64` encoding. + +## Write a text in header and footer + +Customize text in headers or footers using the [Header](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Header) and [Footer](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Footer) properties in [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html). Set `Type` to **Text**, define `Value` for the text, `Position` for x/y coordinates, and `Style` for color or font size. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Navigations + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + public List HeaderContent = new List + { + new PdfHeaderFooterContent() { Type = ContentType.Text, Value = "Gantt Chart PDF Export Header", Position = new PdfPosition() { X = 0, Y = 50 }, Style = new PdfContentStyle() { TextBrushColor = "#000000", FontSize = 13 } } + }; + public List FooterContent = new List + { + new PdfHeaderFooterContent() { Type = ContentType.Text, Value = "Gantt Chart PDF Export Footer", Position = new PdfPosition() { X = 0, Y = 350 }, Style = new PdfContentStyle() { TextBrushColor = "#000000", FontSize = 13 } } + }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); + PdfHeader Header = new PdfHeader() + { + FromTop = 0, + Height = 100, + Contents = HeaderContent + }; + PdfFooter Footer = new PdfFooter() + { + FromBottom = 250, + Height = 100, + Contents = FooterContent + }; + exportProperties.Header = Header; + exportProperties.Footer = Footer; + await Gantt.ExportToPdfAsync(exportProperties); + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/rDhyiDXArUzpgPqb?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Draw a line in header and footer + +Customize lines in headers or footers using the [Header](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Header) and [Footer](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Footer) properties in [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html). Set `type` to **Line**, define `points` for start/end coordinates, `pageNumberType` for position, and `style` for color, width, or dash style. + +Supported line styles are, + +* Dash +* Dot +* DashDot +* DashDotDot +* Solid + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt +@using Syncfusion.Blazor.Grids +@using Syncfusion.Blazor.Navigations + + + + + + + +@code { + private List TaskCollection { get; set; } + private SfGantt Gantt; + private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; + public List HeaderContent = new List + { + new PdfHeaderFooterContent() { Type = ContentType.Line, Points = new PdfPoints() { X1 = 0, Y1 = 4, X2 = 685, Y2 = 4 }, Style = new PdfContentStyle() { PenColor = "#000080", DashStyle = PdfDashStyle.Solid } } + }; + public List FooterContent = new List + { + new PdfHeaderFooterContent() { Type = ContentType.Line, Points = new PdfPoints() { X1 = 0, Y1 = 350, X2 = 685, Y2 = 350 }, Style = new PdfContentStyle() { PenColor = "#000080", DashStyle = PdfDashStyle.Solid } } + }; + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) + { + if (args.Item.Id == "PdfExport") + { + GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); + PdfHeader Header = new PdfHeader() + { + FromTop = 0, + Height = 100, + Contents = HeaderContent + }; + PdfFooter Footer = new PdfFooter() + { + FromBottom = 250, + Height = 100, + Contents = FooterContent + }; + exportProperties.Header = Header; + exportProperties.Footer = Footer; + await Gantt.ExportToPdfAsync(exportProperties); + } + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public int? ParentID { get; set; } + public string Predecessor { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BZBIWtXKVKPSwLAW?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## See also +- [How to export to PDF?](https://blazor.syncfusion.com/documentation/gantt-chart/pdf-export) +- [How to manage task dependencies?](https://blazor.syncfusion.com/documentation/gantt-chart/task-dependencies) \ No newline at end of file diff --git a/blazor/gantt-chart/holidays.md b/blazor/gantt-chart/holidays.md index f140f5da8e..9c2a413d3e 100644 --- a/blazor/gantt-chart/holidays.md +++ b/blazor/gantt-chart/holidays.md @@ -1,7 +1,7 @@ --- layout: post title: Holidays in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Holidays in Syncfusion Blazor Gantt Chart component and much more. +description: Learn how to configure holidays in the Syncfusion Blazor Gantt Chart component for accurate task scheduling with non-working days. platform: Blazor control: Gantt Chart documentation: ug @@ -9,20 +9,37 @@ documentation: ug # Holidays in Blazor Gantt Chart Component -Non-working days in a project can be displayed in the Gantt Chart component using the [GanttHolidays](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttHolidays.html) property. Each holiday can be defined with the following properties: +The Blazor Gantt Chart component supports holidays to define non-working days, such as national holidays or company closures, that impact task scheduling and project timelines. Holidays override regular working time settings like [WorkWeek](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_WorkWeek) or [IncludeWeekend](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_IncludeWeekend), ensuring tasks do not progress during these periods. In the timeline, holidays appear as highlighted backgrounds with descriptive labels, creating visible gaps in taskbars to reflect scheduling adjustments. Custom CSS classes allow distinct styling for different holiday types (e.g., national vs. company holidays), enhancing visual clarity. Properly configured holidays ensure accurate duration calculations, dependency adjustments, and critical path analysis, aligning project timelines with resource availability and regional requirements. -* `From`: Defines start date of the holiday(s). -* `To`: Defines end date of the holiday(s). -* `Label`: Defines the description or label for the holiday. -* `CssClass`: Formats the holidays label in the Gantt chart. +## Understanding holiday effects on tasks -The following code example shows how to display the non-working days in the Gantt Chart component. +Holidays adjust task scheduling to reflect non-working periods: +- **Duration adjustments**: Task durations exclude holidays, extending end dates. For example, a task starting December 20, 2024, skips a December 25-26 holiday, adjusting its completion to account for these days. +- **Dependency management**: Successor tasks shift to maintain relationships (e.g., FS), ensuring no work occurs during holidays. +- **Critical path integration**: Holidays impact slack calculations when using [EnableCriticalPath](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_EnableCriticalPath), as tasks delayed by holidays may become critical. +- **Resource allocation**: Holidays reduce resource availability, pausing task progress during these periods. + +The [ProjectStartDate](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ProjectStartDate) and [ProjectEndDate](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ProjectEndDate) properties provide context for scheduling, ensuring holidays align with the project timeline. + +## Configure holidays + +Holidays are defined using the [GanttHolidays](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttHolidays.html) property, which accepts an array of holiday objects specifying dates, labels, and styling. Holidays take precedence over settings like `WorkWeek` or `IncludeWeekend`, ensuring tasks do not progress during these periods. + +**Holiday configuration properties** +- `From`: Sets the start date of the holiday (e.g., `new Date('2024-12-25')`). +- `To`: Defines the end date for multi-day holidays (optional for single-day holidays). +- `Label`: Provides a descriptive name (e.g., “Christmas Day”) displayed in the timeline. +- `CssClass`: Applies custom CSS classes for styling holiday appearances. + +The following example configures single and multi-day holidays: + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentId = 5 } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } }; return Tasks; } } - -``` -The following screenshot shows the output of Holidays in Gantt Chart component. +{% endhighlight %} +{% endtabs %} -![Blazor Gantt Chart displays Holidays](images/blazor-gantt-chart-holidays.png) +{% previewsample "https://blazorplayground.syncfusion.com/embed/hjryCZgZfnCCBAeu?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -N> You can refer to our [Blazor Gantt Chart](https://www.syncfusion.com/blazor-components/blazor-gantt-chart) feature tour page for its groundbreaking feature representations. You can also explore our [Blazor Gantt Chart example](https://blazor.syncfusion.com/demos/gantt-chart/default-functionalities) to know how to render and configure the Gantt. \ No newline at end of file +> You can refer to our [Blazor Gantt Chart](https://www.syncfusion.com/blazor-components/blazor-gantt-chart) feature tour page for its groundbreaking feature representations. You can also explore our [Blazor Gantt Chart example](https://blazor.syncfusion.com/demos/gantt-chart/default-functionalities) to know how to render and configure the Gantt. \ No newline at end of file diff --git a/blazor/gantt-chart/how-to/open-add-edit-dialog-dynamically.md b/blazor/gantt-chart/how-to/open-add-edit-dialog-dynamically.md index ba09a7a540..7564f693af 100644 --- a/blazor/gantt-chart/how-to/open-add-edit-dialog-dynamically.md +++ b/blazor/gantt-chart/how-to/open-add-edit-dialog-dynamically.md @@ -1,7 +1,7 @@ --- layout: post title: Open Add Edit Dialog in Blazor Gantt Chart Component | Syncfusion -description: Learn here all about Open Add Edit Dialog Dynamically in Syncfusion Blazor Gantt Chart component and more. +description: Learn how to open add and edit dialogs programmatically in the Syncfusion Blazor Gantt Chart component for efficient task creation and modification. platform: Blazor control: Gantt Chart documentation: ug @@ -11,12 +11,14 @@ documentation: ug Gantt Chart add and edit dialogs can be opened dynamically by using [OpenAddDialog](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.Action.html#Syncfusion_Blazor_Gantt_Action_OpenAddDialog) and [OpenEditDialog](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.Action.html#Syncfusion_Blazor_Gantt_Action_OpenEditDialog) methods. The following code example shows how to open add and edit dialog on separate button click actions. -```cshtml +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + @using Syncfusion.Blazor.Gantt - + @@ -39,31 +41,32 @@ Gantt Chart add and edit dialogs can be opened dynamically by using [OpenAddDial public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public List SubTasks { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 23), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 23), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 04), Duration = "3", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 04), Duration = "3", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 5 } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 06), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 04), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 04), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 5 } }; return Tasks; } } -``` -## Demonstration image for dialogue -![Opening Edit Dialog in Blazor Gantt Chart](../images/blazor-gantt-chart-open-edit-dialog.png) \ No newline at end of file +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VXLeCtANAbQtiBAd?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} \ No newline at end of file diff --git a/blazor/gantt-chart/images/cell-edit.png b/blazor/gantt-chart/images/cell-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..af1496d81a68906a668c1a2075fe2a915019141f GIT binary patch literal 29451 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 literal 0 HcmV?d00001 diff --git a/blazor/gantt-chart/images/editing-dialog.png b/blazor/gantt-chart/images/editing-dialog.png new file mode 100644 index 0000000000000000000000000000000000000000..e20b75ce58fd21ff55292a6cb293e9ea98cc1ae5 GIT binary patch literal 38540 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�e^=U8-dXl+OU*3X?%_`#E|;7l*?DJr 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 literal 0 HcmV?d00001 diff --git a/blazor/gantt-chart/images/endDate-manual.PNG b/blazor/gantt-chart/images/endDate-manual.PNG new file mode 100644 index 0000000000000000000000000000000000000000..07442b4b0a2ee72b30a2aca1d037840469076459 GIT binary patch literal 1226 zcmeAS@N?(olHy`uVBq!ia0y~yU}OZcS97od$ut?wgFuS0ILO_JVcj{Imp~3nx}&cn z1H;CC?mvmFKt5-IM`SSrgP1A^GkON8d;qG6_jGX#sfc@f^I&fbtAJ~un2M8%UrWUS zz5^}^Oa}@rn5-Gv4ObkU!t(59?Cs@N?p3>gp5FC&_wVK64@?9b9=kB~2{T&wu{^LC zFwTNI{`>!b+yD2^ySJzH>-W_E{QCI#^!@v4>i&A4a9I%3bzpn-=jZLy{p0uVvt#_P z%JlTo#pSm5`1XiS=y2Fs^5On%WtMv!Kc;a^@jm`nHfNSo zOPTNUv;oa$-zUi%A=<@#;$|0@3fGU;&G zTk_=mx7Ww}*ZVhfT=91Qms4N+^AA+Q{?=@J`#pA?|3PW(!v5{Y#hd2utE;UQ`UgsN z8<*QMJxFHg1SPruZ{_3}_b`621*PA=kN5w3oPOZ=dWL_$KlgAPC{$uN-pL@N&Qvgm g2At)4_x#}vKl@6l_uH#_VEMz~>FVdQ&MBb@0G*-kX#fBK literal 0 HcmV?d00001 diff --git a/blazor/gantt-chart/images/startDate-manual.PNG b/blazor/gantt-chart/images/startDate-manual.PNG new file mode 100644 index 0000000000000000000000000000000000000000..417cb5fcbc5eabf247fc2d34f988abeeaa8063de GIT binary patch literal 1233 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

    -SXG{Ae?4*o2Yc1WqFu%V`?RQ>stcwhsw4&=D z9Deke4gvwg#!c(AV&%4~bfp@{6{z4^PxN0K8mEC>todXEPVtiTM+3rZVJCQ9FUfNy z;nn-6dlUhuaiPbbop<{92Au|98d9mbmI{NHB#u4-p0Ao3n`WqSZOPWS=1b>-I-Z^3 zWDu#};~dc?C5xR2*Qu@4DS2RQmOe5$AY5N+=@m#a-9TUE_yP$6kLyVikDEw(@`)V* z8tGp*6Qq|>UPH$cO7-OP95pnO&xtCwvaQ&1ppK7I8CB8C$@z>&(aUXg;kl3}8C}>Q z6f2xFGc_|~%d57#yzU6Zb5x?vX>ol#(HI9l*;$NOkq7|0ok(!ujo+_$5 zlbM>sZ%{O^Cz7N6VK0kRydg*Do!uOaV`z+sF4eGy0olwXsN$2#%7?CQ^Wl&>a?tYp zb%VF)V$fht!)+>`(LuK1$0;7;hRpjpo#`J%!D;J%;kuC|c|KnuGg$V+5!a+s)7>%ftwN36|`tYVPSkZ;M-nE2he5Cq0k@J&u7)AU!W3ybNCRb)y{L|jR|dL_GeihKO+ zZnyho2_552pz8l3XkFjkwJ zsKs2%3QLtTc7ZSjxwa=jx0B_3OEdV|&=Mb1q976&$!LBMwQ1G3Q{%&;hXR4ptwD8c zMXMKyJIcKm~`Ch^=b864M};SGPz`)kz5A65RDQ6o1IFL5u@r;+dh0(Hrs>7IoFX`~3l z0a(RGhBUiNTCd#!OS@aQc?LS;wOk&^T^vsu%-xQUV;9r6W2%Zl@7c*U(3pm)YRp`u zbC$W`9{62dRYzOxYEIznhB0vpbiFHLt)TG%5mf~p>*$=Kij=3>anv`C&AuM0bXbmi zxkpJV)@a=Qoe-d&b4o?Z3$TM`!TbsCZJ3+tQUSTsRQ8}Tk_s&6`BO5qBgiC#b`A_j zHlSw1<#qtA!Y8wbP4PYyK_nR0Pjvg!#AnCf<}j2wM*TF4WWm}_p&e?+Z~OX}J`3z%Qzl0zBQOjpGC*?mLkBk z^Ch5LhhoqmKs=0ra}Kc#I5Qyp*-5F-RquHD`ct|j6Y;kAaOE#*r3-K4~ROj7|p4VzCH6jcj%Lf``TyXOQ~k<{vsh!(@bcdO?$ zYVm)woRXw!0Wz>|L{t%O5gt{*IHtoymu-Duh$KjZLn4-4ll@WEa<~N_<{OLH(*#=~{GwCYmY;X-@?ZAmzSs? z5fXMvruQTl+&8+TrzOt!{FKud{Y70+3A|_eh-hO*$`)`m-wf*Ui)r-3|<;K;l z4E>sK-qc%92#(scI>%SQyoCwlz2sW{99>sAn5kM1!*5=KFTJp=y*W%u``p*I+BSu@=8m=ehnbMzF%Ph1j)_4(_ zZgt%*rokAf@=A8P_F=+Kmz-Q^E%h940f*Op3r@{e4=1_GugZnI$tMF9_&ZU>RY~J5 zb#HJyRtuBvXvK@!BUCc3l=_k z$CRifDeh+6@@+W%`ocn#@iGR<))}HUXicH34T(ljFHlKt@EC#MCyCP@nv)~B)>%KL z{$O+1B*UoH@R#?Y<#;hs-7(W&Qq%-@=OPqqvwLxL&uE(llcFut6*aeC=~OrT26T>@ zV{(fU%~qdl=dfa|5>$eib9TR8-M~bAH+DpRKFdi50m)97AcCL;KYZ)Qo?_k=Q0R4K zBmgc>PbQa?Z02ijiO^{iA;Ll~&Br1Z1Kqh4TS9g{Li|J%M#93pea? z{bTI;>znHi4#8L^`Q0{ZQa>CMeHS4Yasd&AuA%JBoZVXLsfykQP&FF6 zv*gj#+Hvv5sZhITU>@PlytN+p05=4a>k;VG*zMDjMh0EXxK0fhYv5P9%~Mef+w9hY zA{H)PvqHy%YnL|fMtt0Q15e*#QWTSi7pU%Epbod&0DE-8k?KF=Ym zC1B><+;yg_`)B#}_oKY(il9NsBJ$Z3Ni~x`uDo&yM~&&N+v04yZV)pf^gX}{%*U4P&^YzsF(+l!I)pbvhdn-YRjT%y$bC`f}hmD9DZ1LkQ!RnD7(!*y|ACMJ%R7vHg z*Vr3bJ`N`l_cl{J(k!(gR%zWo z|AjvIsdxIUPA8d9U*HJ%XhirmkzY)4-buWZ6`5g}h!{z0rla!XGXF`Mj2-j=?u%9{2B?U*^!v@85MYh9Bl z%x1?M)8Y|3Ofe^4AUc7NTx_4Ca{DZvozW;PR_B*Xo6EQ8$|nzK(N4gJquyJy#;Sg& z^~R`e*(46kZ(3$Z*1F#9d$ATYx*kt7k61}nYBUVE8qzGzCCHwc3SHp03oH+(a}SE! zHU%Z?b#$9P7+t7*fElyR2fuj4_1*)uZh$6u_(snoaNipTCs6~@T~#>n<5Z%{OvF%3 zqBof!#OAUq#oQfe-1x0L-Q4<>EoazF1u5nZcLbPHol_-GsNj_C>Z~>5HRDMONHUIR z!^m(p2}6dA{3l6EnZ;^E`;s;iKd9a(shRx9S@G?i*DYxQBR(mUE2`oi^wZdytrMzZ zjZ-J`h2}fCGLGuXnjcd|LGQ+k8Es>gB8-BwLD>*z0XC1nx9 z8zffPBu?mPT(l(K6%`e%K}2!Qh6+MCG>ohMn22sCtkKI}%dR^eiQ(jNf8_&5d7AeI zjogpc4FY+@_4&Sj8x-UIYQgPgI|IZ8k96{xHnE_=AZbBwAC%zQ>B)rF1VL+nORK#H z4cSBMHV4=lAaiX3UT~}Z&=2o_-gn5>?s1DGzT1NC%N;{!W@~w+uv%Qj`F5M8_X%^} z;}bP=WhXiBOtXYduBZj_!t}fcZe5&iUhPzwxa++8AXQxA>V!h{w_Km|0ReE3ovU;y z4MIDtorsOGEz#kL@hC`t4?XplDlmRKZv6s_b=o@0dLv`oa4)z#oJyrQ7a;yVlvEY< z>FFVdIDe@VP!83`n%2q|IICyJ#H=jrJJbVonZb00>2=;ACq0MUs(w&|34n_dX~z{a zmk~%9m|Hr8?yMVV6sl8LoVbR!DYcfA8{GV^hBpx>@6GY*)I^COoOMuOz9tHKz_U5@ zo75Kdq#wqf2+?yq&ohktScvg5`ve4Vrn3QnqtNySF;`XapC_EQ?@=-*exlKM)n>3A zAh=dfsl4?NF6#8V1`L<5!8|vhShrq#{DXAXu(>V62$~&=g-Y<&TO{>mZ_ag7PaHd& zU1nD!kwR9ztl}5PL5?%i4<)g8eKA|l&WjJPE>6n@5oeMYE72h>mg{=bNnAS?(%PTA zoB8y5dGzaOb4MTRdp1cmRy``ZNy&?gjfDscdq>sY0@GQc{pmMBV6V7dWBgJvRc`O4 z^ha56kirmhXiY1@JB@mlSQss*sX_8hA;|Uh?`4?sWJ0QzmR&PAV4Hs)F|;GNzI!}} z!^^8;b$;}x#!4$3;A9&HLE@Kr_qP21IBNu+GV&hX%84uHq5i3+GuUz&G? zb|(L<!%jHi%lYNVMQt<;HX{w>;Y-(p9UVA{>)UwdB zo)$Dk3AQ4C-c()blifSF2mY`|41y-?%z2(J1qRVZ^;Cilz~cNTf_U_Era1Jg+P*6GOE5VVF*TM?JGzoBtTnqAgVPTPvJF9C^*idSY16gIk-)XfaPD)-N`a`ELXB0ww z>~&Im6r-FKXbBYXx%NCwqO28`0bV1fvsowH-P+LN*AXRcbgL%=qBOHW#4rVUqi>X_ z=Ud%VASh-9&fO*Vc2dyqlaZY-fv5d+d9@1Z%D4i&1$8^%)V^z!4FCvl)f3lb+L}#O z?c$H24q2$CtMa+u-DxNz1Q+p0vKc^bhxVrk_cz;46bZZRwY{EQOFq5V!ZkfnyxcV=Q6h_n=?v_BHxRqs*B4C# zBd5VS&f9AKeubS%8i1JskiNQ|Z8(TZ3t+(V@fmlZSTToAO<(NxE@~Qg+Spi%d#u$G)pQl8aBY<2buca6JE#RvHKuibJ}5-<&gJ1??e?~n zU`y~B&BY>!Nl%#5$eS~*2s+zoPyx5$tG!?322)V$v6LvIkcEZC3D|be@^n8k0j2Pn z<(&irLd)_n6;dp8_-8V>f5W7{=$(T%c zNA$>dnOgi@v1FQLi{T?_VcUKJG;`1R*-l{DxOgyCLb87yf> zGQ*OaVho{y3rCT9PqWdzTd!Vew|Y0jQ3>e=Z^Z-W->IibXYte({EG!=OFDC$$G0wh z>dPia*}9x9e5OLok9gV-0LrKhhy;(FANN#nrmD38NX{gIK|@x(xI`f-Ddp6))eZ#S>X5{^mfJ*KYkd@LizJ(edN@ zK&oDduXGp0s{Mk(fQihd%s3RWvDdmJOIm`gO=_xB7D$?eOx4qX&}t0`qT>a+5L^V4 zvb~!E{XW~^Xo-JJD!EYW2FA=#uFi?+!=1bL$^ZxEwIFGzbiMh#-B^%Gd-zCedm|fz zjjMY59d=yI19uLN0Z?3~$HFmgnD^wxr+MXWp-0cc!7?&*zmrR7Q)DwM+G^Ii))|8v zY=CQ|8iV;mdWd09F)6e@;#ZieI)0Nn{#Q~xH>9bm*7ktM*k3AB$=>)Sww{9Qx^(Bw zfALT(b+uMNgrujxCL32b1%oTVplbbZ$A*CK3<*FF>!(g44fXO1Gx$)^|bdu7;8YeVd*yf5k|J17J~wrMkM(%=!!}_+lDa z-=gQxvIbnNHK~$9E?-flsdt6E68~NAZ{~Fzw@)yAs_G0i-^eT&>-@UYo@HOoWmun^ z{X{Eq#DjqiHv8ea!Fbj-!p3F%uTFjLBjAYyT^4}Tq$ALZar#ScV*0I_C$TPpiLdCF zgaySP#;Iy{ww~;#bqfxtk!poKTHv6p>zU&n1fUCm0hx_mx3$3BnG@%im)1@KZy;F1 zN6^0dSk?etv?1zbWP~^1SE{Lsk-k8k&9iwE5=AltLhT6J z<&kALF4EtHxk^rsES=CSKYw3fXI&lYu^4_1-Il?<{4FwXh?9eg5yjJXBn;emk4Z3C_xS|7JeVYpa;4*yVecL=d zJix+FH$x`($e-vfsBSqogd{L-;$* z{m75evGLC2(2laCpxAe5qtNj`4-J+Mf|`vbEGO8vfP2O6bsQ0r_0xW?eyg% zFkqE_EaKM)VwuqUDEk$YzK0G&wlpIs)1$gw! z2+ZU0s_|%Z((3-_BTjTis`No+1G1<^XV6Qs5z7z5-Y=i1c1$WBV5vxfFa6`p-!N2y z64-{E_Tr0ylEM6%C&Gy!7#%geDcEkb4}1WSnOgOpIMgA2R^_MVku z2eI$s?3|p2h46%g2jmNGSDwt7Yp{T9?fsz42_U*H@6WWkI-y_v>rHMtRMe2v2dm;` z?|<48MsvdE!11~U{15fF0sV^Q54b}hyKwiWi%G1PR#shxo#$u7O?)aO*GeiATl>p` zsNH|RE7CLq-MCNjcc{6V%mD8*hDCK7_~UAunwtK#A?znZD_0AsqXFj1K`W>*7tCl_ z`DKs*#q^~B51oNpSm_^NPARGN()W{f{cK^)IN9_>x!1?N71yidv5?tvdmaFn#*vdP zlGtc;WR^BP?`8m8`_{nuiw&A{h%8!g zaB;1{c5zpzf#<%}+abOAWe%aWoZQ?-kCBhQT};1`Ugt;o%=YUao_@IebO*l-a69TF zrL%T@g=eFpm#qNw_GE{kcc;;UO%Sf2XR&WTKCdim&V?NVIyCYDC(_cx3%={Ja$9fb z(;b3pki;HRcQ#>C)@X{iAekc$teeS z=tsX^uUfQiP}iSNAIV4s_^a*;v_w}_DaVbQ}i2&qEH*~ zyc5(OE_yxv748?FJOV7zEC1HEeKvCVn@j%_0JZ2lnfLJl_sfSgZOJaP8msrG!$I;^ zw1mROES2|XgNrO~*gj0nSrqIkbsbAmVkaLr@!>P#0q9*J6%as(Se}DBd1T^LqlPr0O?=_tgTM7hk?i@ zzOOknK;Ms;9_mN}7igy>oG5ujP<97^2eNXzXWK50%3$fUqxkSfk38Fc`w_1hi`;rj zc~C4-fQK3z{4onI;~g-oG5hyXl=kcSUNbWmMjH9M5!GeAGvau+o+)>NbnyyGYeX`< zZcsVi+exAwv<%Ew1S_S?(eP6TqVy@Ft#EMt2YI~1T3d8RY^vn~cgW)gmby@WRkeV9 zS%igsAgxk{Myd;Vwi{UtbuxS}pREUugOzL=!xh;IRwS7tXx&`Hm%OwC2MwoNY4<#UA_S9P>8GPaF|J{}S|8&!VhXfCb12!JuJA-HE{A?#FPpHz@S6`V+;tYm3%&`ui^^=x*?aZU-Y(;6pGM{cE<`k{ns-?dIkN zPHYb&eWyW#ha5Pj*{k-0)v@M3wNXkh?a~4N5jUAw7~L5)eDH72Pk&8Z-IhuW`;Zhu z$eryigq;K`mUZIvLqv&*iK{%pMcz62n-v^pq1(g%>hSpQ%}w{$GgrHHOz?_;yOiXi zuZN3^OP%{*kwgz)A`3s-<*KSvKsPd<;I4&|HCpgv!Or#ncnhnR_JY|g z%_+x&h5w-_uao1)JH!3?&=bB^Pfu3;8}AJ&T+ZBe=D{Lm4=(O)Za^Z#IaV*^ZTU|@ z-IBqvwR#|?wFIbGC@Fl1pnw5a#tAsU>wq?yIm-y`Sm>7_vXH*tlLp}IE}$o-o;wXd zvp{_l=Qk20l+pmo$(4bWhZndup!a2rxGi;LFIq`rI$U_|!Kq;O8K?oOuwU-d0=;hI zru6@**pki)Z`$)7d;7Xx%)$N z84w7h#+{9JqW@a1&M?is_TnTsrj_iRGxUKwnScjoM*{;!_u2ILI_PDQ9~BQ(1Mj*5 pj{hA`0^TwP4X_#=J-u`P - + - +

    Task Name: @((context as TaskData).TaskName) @@ -42,27 +55,27 @@ The Gantt Chart component maps any data source fields to [GanttLabelSettings](ht public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentID = 5, } }; return Tasks; } @@ -73,6 +86,8 @@ The Gantt Chart component maps any data source fields to [GanttLabelSettings](ht color: black !important; } -``` -![Blazor Gantt Chart with Task Label](images/blazor-gantt-chart-task-label.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/LtLIDkVIpzpsrlhR?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} \ No newline at end of file diff --git a/blazor/gantt-chart/managing-tasks.md b/blazor/gantt-chart/managing-tasks.md index c82cdf05e0..e2a795ad2b 100644 --- a/blazor/gantt-chart/managing-tasks.md +++ b/blazor/gantt-chart/managing-tasks.md @@ -3,42 +3,90 @@ layout: post title: Managing Tasks in Blazor Gantt Chart Component | Syncfusion description: Checkout and learn here all about Managing Tasks in Syncfusion Blazor Gantt Chart component and more. platform: Blazor -control: Gantt Chart +control: Managing tasks documentation: ug --- # Managing Tasks in Blazor Gantt Chart Component -The [Blazor Gantt Chart](https://www.syncfusion.com/blazor-components/blazor-gantt-chart) component has options to dynamically insert, delete, and update tasks in a project. The primary key column is necessary to manage the tasks and perform CRUD operations in Gantt Chart. To define the primary key, set the `GanttColumn.IsPrimaryKey` property to `true` in the column. +Managing tasks in the Blazor Gantt Chart component enables dynamic project updates, such as inserting, deleting, or editing tasks and dependencies, by enabling [AllowAdding](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowAdding), [AllowDeleting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowDeleting), [AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowEditing), and [AllowTaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowTaskbarEditing). A primary key column, defined by [GanttColumn.IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html#Syncfusion_Blazor_Gantt_GanttColumn_IsPrimaryKey) set to **true** (e.g., on id), ensures reliable CRUD operations and task identification. Editing modes include cell editing for quick TreeGrid updates, dialog editing for comprehensive changes, taskbar dragging for duration or date adjustments, and connector line dragging for dependencies. Customize dialogs with templates or fields using [AddDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AddDialogFields) and [EditDialogFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_EditDialogFields). Methods like [AddRecordAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AddRecordAsync__0_System_Nullable_System_Int32__System_Nullable_Syncfusion_Blazor_Gantt_RowPosition__System_Object_), [DeleteRecordAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_DeleteRecordAsync_System_Nullable_System_Int32__), and [UpdateRecordByIDAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_UpdateRecordByIDAsync__0_) support programmatic management. Ensure valid [GanttTaskFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html) mappings and a primary key to enable editing seamlessly. -## Cell edit type and its params +The following code example demonstrates editing in the Gantt component. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt + + + + + + +@code{ + private List TaskCollection { get; set; } + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + + public class TaskData + { + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime? EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public string Predecessor { get; set; } + public int? ParentID { get; set; } + } -The `GanttColumn.EditType` is used to customize the edit type of the particular column. You can set the `GanttColumn.EditType` based on data type of the column. + public static List GetTaskCollection() + { + List Tasks = new List(); + Tasks.Add(new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }); + Tasks.Add(new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }); + Tasks.Add(new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentID = 1 }); + Tasks.Add(new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentID = 1 }); + Tasks.Add(new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 11), EndDate = new DateTime(2022, 04, 18), }); + Tasks.Add(new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentID = 5 }); + Tasks.Add(new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentID = 5 }); + Tasks.Add(new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentID = 5 }); + return Tasks; + } +} -* [NumericTextBox](https://blazor.syncfusion.com/documentation/numeric-textbox/getting-started) component for integers, double, and decimal data types. +{% endhighlight %} +{% endtabs %} -* [TextBox](https://blazor.syncfusion.com/documentation/textbox/getting-started) component for string data type. +{% previewsample "https://blazorplayground.syncfusion.com/embed/LXBIWDWeiYcZSwrs?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -* [DropDownList](https://blazor.syncfusion.com/documentation/dropdown-list/getting-started) component for list data type. +Editing feature requires a primary key column for CRUD operations. While defining columns in Gantt using the [GanttColumns](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumns.html) property, it is mandatory that any one of the columns, must be a primary column. By default, the [Id](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Id) column will be the primary key column. If `Id` column is not defined, we need to enable [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html#Syncfusion_Blazor_Gantt_GanttColumn_IsPrimaryKey) for any one of the columns defined in the `GanttColumns` property. -* [DatePicker](https://blazor.syncfusion.com/documentation/datepicker/getting-started) component for date values. +## Cell edit type and its params -* [DateTimePicker](https://blazor.syncfusion.com/documentation/datetime-picker/getting-started) component for datetime type. +The [GanttColumn.EditType](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html#Syncfusion_Blazor_Gantt_GanttColumn_EditType) is used to define the edit type for any particular column. You can set the `GanttColumn.editType` based on data type of the column. -* [Checkbox](https://blazor.syncfusion.com/documentation/check-box/getting-started) component for boolean type. +Below is the combined content from the provided markdown sections in bullet points, as requested, ensuring clarity and conciseness while preserving the original information: -Also, you can customize model of the `GanttColumn.EditType` component through the `GanttColumn.EditorSettings`. +- **Cell edit types and components**: + - **numericedit**: Uses the [NumericTextBox](https://blazor.syncfusion.com/documentation/numeric-textbox/getting-started) component for editing integers, doubles, and decimals. + - **defaultedit**: Uses the [TextBox](https://blazor.syncfusion.com/documentation/textbox/getting-started) component for editing string data. + - **dropdownedit**: Uses the [DropDownList](https://blazor.syncfusion.com/documentation/dropdown-list/getting-started) component to display all unique values for a field. + - **booleanedit**: Uses the [Checkbox](https://blazor.syncfusion.com/documentation/check-box/getting-started) component for editing boolean data. + - **datepickeredit**: Uses the [DatePicker](https://blazor.syncfusion.com/documentation/datepicker/getting-started) component for editing date data. + - **datetimepickeredit**: Uses the [DateTimePicker](https://blazor.syncfusion.com/documentation/datetime-picker/getting-started) component for editing date-time data. -The following table describes cell edit type component and their corresponding edit params of the column. +- **Customization**: + - You can customize model of the `GanttColumn.EditType` component through the `GanttColumn.EditorSettings`. -Component |Example ------|----- -[NumericTextBox](https://blazor.syncfusion.com/documentation/numeric-textbox/getting-started) | @(new { @params = new { format = "n"} }) -[TextBox](https://blazor.syncfusion.com/documentation/textbox/getting-started) | - -[DropDownList](https://blazor.syncfusion.com/documentation/dropdown-list/getting-started) | @(new { @params = new { value = "Germany"} }) -[DatePicker](https://blazor.syncfusion.com/documentation/datepicker/getting-started) | @(new { @params = new { format = "yyyy-MM-dd"} }) -[DateTimePicker](https://blazor.syncfusion.com/documentation/datetime-picker/getting-started) | @(new { @params = new { strictMode = true} }) -[Checkbox](https://blazor.syncfusion.com/documentation/check-box/getting-started) | @(new { @params = new { checked = true} }) +- **Edit type parameters**: + - **numericedit**: Supports parameters like `Decimals: 2`, `Value: 5`. + - **dropdownedit**: Supports parameters like `Value: 'Germany'`. + - **booleanedit**: Supports parameters like `Checked: true`. + - **datepickeredit**: Supports parameters like `Format: 'dd.MM.yyyy'`. + - **datetimepickeredit**: Supports parameters like `Value: new Date()`. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -106,13 +154,13 @@ Component |Example {% previewsample "https://blazorplayground.syncfusion.com/embed/VXVIsNjUCkvqfHQC?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -N> If edit type is not defined in the column, then it will be considered as the **StringEdit** type (Textbox component). +> If edit type is not defined in the column, then it will be considered as the **StringEdit** type (Textbox component). ## Cell edit template -The cell edit template is used to add a custom component for a particular column when the column is edited. +The cell edit template feature in Syncfusion Blazor Gantt Chart component allows you to customize the editing interface of individual cells by embedding custom components or HTML elements. Instead of using the default editor such as a textbox, you can define a template that provides a tailored editing experience such as a dropdown, date picker, or checkbox based on your application's requirements. This is especially useful when you need more control over how data is entered or displayed during editing. -The following code example describes, how to define the Edit template for a particular column. +The following code example demonstrates how to define an edit template for a specific column, where the **TaskName** field is rendered using a dropdown. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -194,9 +242,9 @@ The following code example describes, how to define the Edit template for a part ## Disable editing for particular column -You can disable editing for particular columns by using the [GanttColumn.AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html#Syncfusion_Blazor_Gantt_GanttColumn_AllowEditing) property. +You can disable editing for particular columns, by using the [GanttColumn.AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html#Syncfusion_Blazor_Gantt_GanttColumn_AllowEditing) property. -In the following demo, editing is disabled for the `TaskName` column. +In the following demo, editing is disabled for the **TaskName** column. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -257,7 +305,9 @@ In the following demo, editing is disabled for the `TaskName` column. ## Troubleshoot: Editing works only when primary key column is defined -Editing feature requires a primary key column for CRUD operations. While defining columns in Gantt using the `GanttColumns` property, any one of the columns must be a primary column. By default, the `Id` column will be the primary key column. If `Id` column is not defined, you need to enable `IsPrimaryKey` for any one of the columns defined in the `GanttColumns` property. +The editing feature in the Syncfusion Blazor Gantt Chart component requires a primary key column to perform CRUD operations. When defining columns using the [GanttColumns](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumns.html) property, at least one column must be marked as the primary key. + +By default, the [Id](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Id) column is considered the primary key. If the `Id` column is not defined, you must explicitly set the [IsPrimaryKey](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html#Syncfusion_Blazor_Gantt_GanttColumn_IsPrimaryKey) property to true for one of the columns in the `GanttColumns` collection to enable editing functionality. ## Touch interaction @@ -273,19 +323,24 @@ Action |Description ### Task dependency editing -Tap the taskbar to initiate the taskbar editing for predecessors. Once it enters the edited state, `tap` the left or right connector point to initiate the task [dependencies](https://blazor.syncfusion.com/documentation/gantt-chart/managing-tasks#task-dependency-editing) editing. The dialog will be rendered with the message `Choose another task` and `Cancel` button. +You can tap the left/right connector point to initiate task [dependencies](https://blazor.syncfusion.com/documentation/gantt-chart/managing-tasks#task-dependency-editing) edit mode and again tap another taskbar to establish the dependency line between two taskbars. -![Task Dependency Editing in Blazor Gantt Chart](images/dependency-editing-touch.png) +Once the dependency edit mode is initiated, a dialog appears with the message **Choose another task** and a **Cancel** button. Tapping another taskbar will prompt a second dialog with the message **Select the connector position** and a tooltip near the second taskbar showing **Left** and **Right** buttons. Selecting one of these buttons establishes the dependency relationship between the two tasks. You can click the **Cancel** button at any time to exit the edit mode. -Click the `Cancel` button to cancel the edit action and to continue editing, tap another taskbar to establish the dependency line between the two taskbars. +![Task Dependency Editing in Blazor Gantt Chart](images/dependency-editing.png) -Once the second taskbar is tapped, the dialog will display a message `Select the connector position` and `Cancel` button. A tooltip is also displayed near the second taskbar with the `Left` and `Right` buttons. Click any button to establish a dependency relationship between the two tasks. +The following table explains the taskbar state in dependency edit mode. -![Task Dependency Editing in Blazor Gantt Chart](images/dependency-editing.png) +Taskbar state |Description +-----|----- +Parent taskbar | You cannot create dependency relationship to parent tasks.
    ![Parent taskbar](images/parent-taskbar.PNG) +Taskbar without dependency | If you tap a valid child taskbar, it will create `FS` type dependency line between tasks, otherwise exits from task dependency edit mode.
    ![Valid taskbar](images/valid-taskbar.PNG) +Taskbar with dependency | If you tap the second taskbar, which has already been directly connected, it will ask to remove it.
    ![Invalid taskbar](images/invalid-taskbar.PNG) +Removing dependency | Once you tap the taskbar with direct dependency, then confirmation dialog will be shown for removing dependency.
    ![Confirm dialog](images/confirm-dialog.PNG) -## Editing tooltip +## Taskbar editing tooltip -It is possible to enable or disable the tooltip while performing editing actions on the taskbar like left resizing, right resizing, dragging, and progress resizing by using the [GanttTooltipSettings.ShowTooltipOnEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTooltipSettings-1.html#Syncfusion_Blazor_Gantt_GanttTooltipSettings_1_ShowTooltipOnEditing) property. By default, this property is set to 'true.' +The taskbar editing tooltip can be customized using the [GanttTooltipSettings.ShowTooltipOnEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTooltipSettings-1.html#Syncfusion_Blazor_Gantt_GanttTooltipSettings_1_ShowTooltipOnEditing) property. By default, this property is set to **true**. The following code example shows how to customize the taskbar editing tooltip in Gantt Chart. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -422,4 +477,10 @@ The taskbar editing tooltip can be customized using the [GanttTooltipSettings.Ed {% endhighlight %} {% endtabs %} -{% previewsample "https://blazorplayground.syncfusion.com/embed/BthoiDjqLVZxPYek?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} \ No newline at end of file +{% previewsample "https://blazorplayground.syncfusion.com/embed/BthoiDjqLVZxPYek?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## See also +- [How to add new tasks?](https://blazor.syncfusion.com/documentation/gantt-chart/adding-new-tasks) +- [How to delete tasks?](https://blazor.syncfusion.com/documentation/gantt-chart/deleting-tasks) +- [How to manage task dependencies?](https://blazor.syncfusion.com/documentation/gantt-chart/task-dependencies) +- [How to configure critical path?](https://blazor.syncfusion.com/documentation/gantt-chart/criticalpath) \ No newline at end of file diff --git a/blazor/gantt-chart/pdf-export.md b/blazor/gantt-chart/pdf-export.md index 60a7f84a51..38208f29ac 100644 --- a/blazor/gantt-chart/pdf-export.md +++ b/blazor/gantt-chart/pdf-export.md @@ -1,1225 +1,34 @@ --- layout: post title: PDF Export in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about PDF Export in Syncfusion Blazor Gantt Chart component and much more. +description: Export Gantt charts to PDF in Syncfusion Blazor Gantt with blob objects, single-page layouts, themes, and advanced customization options. platform: Blazor -control: Gantt Chart +control: PDF export documentation: ug --- # PDF Export in Blazor Gantt Chart Component -The PDF export feature enables exporting Gantt chart data to a PDF document. To perform the export, use the [ExportToPdfAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ExportToPdfAsync) method. Ensure that PDF export is enabled in the Gantt chart component by setting the [AllowPdfExport](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowPdfExport) property to true. +The PDF export feature enables exporting Blazor Gantt chart data to a PDF document. To perform the export, use the [ExportToPdfAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ExportToPdfAsync) method. Ensure that PDF export is enabled in the Gantt chart component by setting the [AllowPdfExport](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowPdfExport) property to true. +PDF export in the Blazor Gantt Chart component enables exporting project data to PDF documents for sharing or archiving, using the [ExportToPdfAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ExportToPdfAsync) method. with [AllowPdfExport](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowPdfExport) set to**true**. This feature supports exporting timelines, tasks, and dependencies, with options for indicators via `base64` images, blob objects for previews, single-page layouts, multiple Gantt instances in one file, and themes like Material or Bootstrap. Focus on auto-scheduled tasks for accurate export, as manual scheduling is not currently supported. -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Navigations - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - await Gantt.ExportToPdfAsync(); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/rZLIsjZgrAtEMygE?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -## Customize the PDF export - -The PDF export functionality in the Syncfusion® Gantt Chart provides extensive customization options through the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. By configuring the properties within this class, you can control the layout, format, and content of the exported PDF. This customization ensures that the PDF accurately represents the Gantt chart's structure and allows for tailored exports. - -### Customize file name for exported document -The PDF export functionality in the Syncfusion® Gantt Chart allows you to customize the file name of the exported document. By configuring the [FileName](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_FileName) property within the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class, you can assign a specific name to the generated PDF. This is especially useful for keeping your exported documents organized and easily identifiable. - -In this example, the exported PDF will be saved as `ProjectSchedule.pdf`. - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Navigations - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); - exportProperties.FileName = "ProjectSchedule.pdf"; - await Gantt.ExportToPdfAsync(exportProperties); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/BjBSCZNAhALZXWKG?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### How to add a text in header/footer - -The PDF export functionality of the Gantt Chart allows you to add and style custom text in the header or footer of the exported PDF document. This customization can be achieved using the [Header](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Header) and [Footer](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Footer) properties of the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. By configuring these properties, you can include important information, such as titles, project names, or other relevant details, to enhance the exported document. - -The following sample code demonstrates how to add custom text and apply styling to the header and footer sections of the exported PDF document, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Navigations - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - public List HeaderContent = new List - { - new PdfHeaderFooterContent() { Type = ContentType.Text, Value = "Gantt Chart PDF Export Header", Position = new PdfPosition() { X = 0, Y = 50 }, Style = new PdfContentStyle() { TextBrushColor = "#000000", FontSize = 13 } } - }; - public List FooterContent = new List - { - new PdfHeaderFooterContent() { Type = ContentType.Text, Value = "Gantt Chart PDF Export Footer", Position = new PdfPosition() { X = 0, Y = 350 }, Style = new PdfContentStyle() { TextBrushColor = "#000000", FontSize = 13 } } - }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); - PdfHeader Header = new PdfHeader() - { - FromTop = 0, - Height = 100, - Contents = HeaderContent - }; - PdfFooter Footer = new PdfFooter() - { - FromBottom = 250, - Height = 100, - Contents = FooterContent - }; - exportProperties.Header = Header; - exportProperties.Footer = Footer; - await Gantt.ExportToPdfAsync(exportProperties); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/rDhyiDXArUzpgPqb?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### How to draw a line in header/footer - -You can add lines to the Header or Footer area of the exported PDF document using the [Header](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Header) and [Footer](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_Footer) properties in the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. - -Supported line styles are, - -* Dash -* Dot -* DashDot -* DashDotDot -* Solid - -The following sample code demonstrates adding line in the Header and Footer section of the exported document, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Navigations - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - public List HeaderContent = new List - { - new PdfHeaderFooterContent() { Type = ContentType.Line, Points = new PdfPoints() { X1 = 0, Y1 = 4, X2 = 685, Y2 = 4 }, Style = new PdfContentStyle() { PenColor = "#000080", DashStyle = PdfDashStyle.Solid } } - }; - public List FooterContent = new List - { - new PdfHeaderFooterContent() { Type = ContentType.Line, Points = new PdfPoints() { X1 = 0, Y1 = 350, X2 = 685, Y2 = 350 }, Style = new PdfContentStyle() { PenColor = "#000080", DashStyle = PdfDashStyle.Solid } } - }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); - PdfHeader Header = new PdfHeader() - { - FromTop = 0, - Height = 100, - Contents = HeaderContent - }; - PdfFooter Footer = new PdfFooter() - { - FromBottom = 250, - Height = 100, - Contents = FooterContent - }; - exportProperties.Header = Header; - exportProperties.Footer = Footer; - await Gantt.ExportToPdfAsync(exportProperties); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/BZBIWtXKVKPSwLAW?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### How to change the page orientation - -The PDF export functionality allows you to customize the page orientation of the exported document. By setting the [PageOrientation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_PageOrientation) property in the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class, you can choose between [Portrait](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PageOrientation.html#Syncfusion_Blazor_Grids_PageOrientation_Portrait) (default) and [Landscape](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PageOrientation.html#Syncfusion_Blazor_Grids_PageOrientation_Landscape) orientations based on your requirements. - -The following code snippet demonstrates how to set the page orientation to Landscape for the exported PDF document, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Navigations - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); - exportProperties.PageOrientation = Syncfusion.Blazor.Grids.PageOrientation.Landscape; - await Gantt.ExportToPdfAsync(exportProperties); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/BtVyMjNgBzDbCnDU?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### How to change the page size - -The PDF export functionality allows you to customize the page size of the exported document to suit your needs. By setting the [PageSize](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfPageSize.html) property in the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class, you can select from various standard page sizes. The default page size is Letter, but other options like A4, A3, and others. - -Supported page sizes are: -* Letter -* Note -* Legal -* A0 -* A1 -* A2 -* A3 -* A5 -* A6 -* A7 -* A8 -* A9 -* B0 -* B1 -* B2 -* B3 -* B4 -* B5 -* Archa -* Archb -* Archc -* Archd -* Arche -* Flsa -* HalfLetter -* Letter11x17 -* Ledger - -The following code demonstrates how to change the page size to A4 for the exported PDF document, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Navigations - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); - exportProperties.PageSize = Syncfusion.Blazor.Grids.PdfPageSize.A4; - await Gantt.ExportToPdfAsync(exportProperties); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/BNhyiZZKhzLBWLhu?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### Export current view records - -The PDF export functionality allows you to export only the records that are currently in view on the Gantt chart to a PDF document. This can be achieved by enabling the [IsCurrentViewExport](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfExportEventArgs.html#Syncfusion_Blazor_Gantt_PdfExportEventArgs_IsCurrentViewExport) boolean argument in the [PdfExporting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfExporting) event. - -N> Exporting current view records is only applicable when the virtualization feature is enabled, and it does not retain the state of collapsed rows during export. - -The following code demonstrates how to use the `PdfExporting` event to export current view data of the Gantt chart to a PDF document, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Navigations - - - - - - - - - - - - - - - - - - - - -@code { - private SfGantt Gantt { get; set; } - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - private List TaskCollection { get; set; } - protected override void OnInitialized() - { - this.TaskCollection = VirtualData.GetTreeVirtualData(30); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - await Gantt.ExportToPdfAsync(); - } - } - public void PdfExportingHandler(PdfExportEventArgs args) - { - args.IsCurrentViewExport = true; - } - public class VirtualData - { - public static List GetTreeVirtualData(int count) - { - List DataCollection = new List(); - Random rand = new Random(); - var x = 0; - int duration = 0; - DateTime startDate = new DateTime(2000, 1, 5); - DateTime endDate = new DateTime(2000, 1, 12); - string[] assignee = { "Allison Janney", "Bryan Fogel", "Richard King", "Alex Gibson" }; - string[] reporter = { "James Ivory", "Jordan Peele", "Guillermo del Toro", "Gary Oldman" }; - for (var i = 1; i <= count / 5; i++) - { - var name = rand.Next(0, 100); - TaskData Parent = new TaskData() - { - ID = ++x, - TaskName = "Task " + x, - StartDate = startDate, - EndDate = startDate.AddDays(26), - Duration = "20", - Assignee = "Mark Bridges", - Reporter = "Kobe Bryant", - Progress = 50, - }; - DataCollection.Add(Parent); - for (var j = 1; j <= 4; j++) - { - startDate = startDate.AddDays(j == 1 ? 0 : duration + 2); - duration = 5; - DataCollection.Add(new TaskData() - { - ID = ++x, - TaskName = "Task " + x, - StartDate = startDate, - EndDate = startDate.AddDays(5), - Duration = duration.ToString(), - Assignee = assignee[j - 1], - Reporter = reporter[j - 1], - Progress = 50, - ParentID = Parent.ID, - }); - } - } - return DataCollection; - } - } - public class TaskData - { - public int ID { get; set; } - public string TaskName { get; set; } - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public string Assignee { get; set; } - public string Reporter { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/hjhyWjtqBfpHsisd?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### How to export Gantt chart with custom timeline range - -The PDF export functionality allows you to export with custom timeline range of the Gantt chart to the PDF document. To specify the range, set the [RangeStart](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfExportEventArgs.html#Syncfusion_Blazor_Gantt_PdfExportEventArgs_RangeStart) and [RangeEnd](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfExportEventArgs.html#Syncfusion_Blazor_Gantt_PdfExportEventArgs_RangeEnd) arguments within the [PdfExporting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfExporting) event. The `RangeStart` argument defines the start date, and the `RangeEnd` argument defines the end date of the timeline range. - -The following code demonstrates how to use the `RangeStart` and `RangeEnd` arguments of the PdfExporting event to export a custom timeline range of the Gantt chart to a PDF document, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Navigations - - - - - - - - - - - - - - - - - - - - -@code { - private SfGantt Gantt { get; set; } - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - private List TaskCollection { get; set; } - protected override void OnInitialized() - { - this.TaskCollection = VirtualData.GetTreeVirtualData(30); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - await Gantt.ExportToPdfAsync(); - } - } - public void PdfExportingHandler(PdfExportEventArgs args) - { - args.RangeStart = new DateTime(2000, 1, 14); - args.RangeEnd = new DateTime(2000, 05, 12); - } - public class VirtualData - { - public static List GetTreeVirtualData(int count) - { - List DataCollection = new List(); - var x = 0; - int duration = 0; - DateTime startDate = new DateTime(2000, 1, 5); - DateTime endDate = new DateTime(2000, 1, 12); - string[] assignee = { "Allison Janney", "Bryan Fogel", "Richard King", "Alex Gibson" }; - string[] reporter = { "James Ivory", "Jordan Peele", "Guillermo del Toro", "Gary Oldman" }; - for (var i = 1; i <= count / 5; i++) - { - TaskData Parent = new TaskData() - { - ID = ++x, - TaskName = "Task " + x, - StartDate = startDate, - EndDate = startDate.AddDays(26), - Duration = "20", - Assignee = "Mark Bridges", - Reporter = "Kobe Bryant", - Progress = 50, - }; - DataCollection.Add(Parent); - for (var j = 1; j <= 4; j++) - { - startDate = startDate.AddDays(j == 1 ? 0 : duration + 2); - duration = 5; - DataCollection.Add(new TaskData() - { - ID = ++x, - TaskName = "Task " + x, - StartDate = startDate, - EndDate = startDate.AddDays(5), - Duration = duration.ToString(), - Assignee = assignee[j - 1], - Reporter = reporter[j - 1], - Progress = 50, - ParentID = Parent.ID, - }); - } - } - return DataCollection; - } - } - public class TaskData - { - public int ID { get; set; } - public string TaskName { get; set; } - public DateTime? StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public string Assignee { get; set; } - public string Reporter { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/rtByWjjUrpHrtFIB?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### Export hidden columns - -The PDF export functionality allows you to include hidden columns from the Gantt chart in the exported PDF document. To achieve this, set the [IncludeHiddenColumn](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.PdfExportPropertiesBase.html#Syncfusion_Blazor_Grids_PdfExportPropertiesBase_IncludeHiddenColumn) property to true within the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. This ensures that columns not visible in the Gantt chart are included in the PDF export. - -The following code demonstrates how to export hidden columns in the Gantt chart to a PDF document, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Navigations - - - - - - - - - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); - exportProperties.IncludeHiddenColumn = true; - await Gantt.ExportToPdfAsync(exportProperties); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/VtreCNXgVTcKHkcY?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### Customize column width in exported PDF document - -The PDF export functionality allows you to customize the width of columns in the exported PDF document. This can be achieved using the [Width](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html#Syncfusion_Blazor_Gantt_GanttColumn_Width) property in the [GanttColumn](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumn.html) class. By specifying the width for each column, you can tailor the appearance of the exported PDF to your requirements. - -The following code snippet demonstrates how to customize column widths in the exported PDF document using the [Columns](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html#Syncfusion_Blazor_Gantt_GanttPdfExportProperties_Columns) property of the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Navigations -@using Syncfusion.PdfExport - - - - - - - - - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); - exportProperties.Columns = new List() - { - new GanttColumn(){ Field = "TaskID", HeaderText = "Task Id", Width = "200" }, - new GanttColumn(){ Field = "TaskName", HeaderText = "Task Name", Width = "250"}, - new GanttColumn(){ Field = "StartDate", HeaderText = "Start Date", Width = "150"}, - }; - await Gantt.ExportToPdfAsync(exportProperties); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/LtBostXgrIjeKZvL?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -## How to export Gantt chart with specific columns - -### Through property - -The PDF export functionality enables you to export only specific columns from the Gantt chart, rather than exporting all columns by default. To achieve this, set the [Columns](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html#Syncfusion_Blazor_Gantt_GanttPdfExportProperties_Columns) property of the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. This allows you to tailor the exported PDF to include only the columns that are relevant to your needs. - -The following code snippet demonstrates how to configure the `Columns` property to export specific columns from the Gantt chart to a PDF document: - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Navigations -@using Syncfusion.PdfExport - - - - - - - - - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - GanttPdfExportProperties exportProperties = new GanttPdfExportProperties(); - exportProperties.Columns = new List() - { - new GanttColumn(){ Field = "TaskID", HeaderText = "Task Id", Width = "100" }, - new GanttColumn(){ Field = "TaskName", HeaderText = "Task Name", Width = "200"}, - new GanttColumn(){ Field = "StartDate", HeaderText = "Start Date", Width = "150"}, - }; - await Gantt.ExportToPdfAsync(exportProperties); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/hXhIiXZAVoCQueAU?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### Through event - -The PDF export functionality allows you to export only specific columns from the Gantt chart, rather than exporting all columns by default. This can be achieved by using the `Columns` argument in the [PdfExporting](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfExporting) event. +## Export basic Gantt data -The following code demonstrates how to use the `PdfExporting` event to export specific columns of the Gantt chart to a PDF document, +Export Gantt data to PDF by setting [AllowPdfExport](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowPdfExport) to**true** and calling [ExportToPdfAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ExportToPdfAsync), which generates a document with the chart and tree-grid data. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Grids @using Syncfusion.Blazor.Navigations -@using Syncfusion.PdfExport - - - - - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - await Gantt.ExportToPdfAsync(); - } - } - public void PdfExportingHandler(PdfExportEventArgs args) - { - args.Columns = new List() - { - new GanttColumn(){ Field = "TaskID", HeaderText = "Task Id", Width = "100" }, - new GanttColumn(){ Field = "TaskName", HeaderText = "Task Name", Width = "200"}, - new GanttColumn(){ Field = "StartDate", HeaderText = "Start Date", Width = "150"}, - }; - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - public string Predecessor { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1, Predecessor = "2" }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 , Predecessor = "3" }, - new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, - new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, - new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, - new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/hXVoCjXAVSBmCcUQ?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -## Customizing taskbar appearance - -### Through property - -The PDF export functionality allows you to customize the appearance of taskbars in the exported PDF document using the [TaskbarColor](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.PdfGanttStyle.html#Syncfusion_Blazor_Gantt_PdfGanttStyle_TaskbarColor) property in the [GanttPdfExportProperties](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttPdfExportProperties.html) class. This property enables you to set colors for various types of taskbars, including: - -* Parent Taskbars -* Child Taskbars -* Milestones -* Critical Paths -* Manual Taskbars -* Baselines - -By configuring the TaskbarColor property, you can format these taskbars to match your desired color scheme. The following code snippet demonstrates how to use the `TaskbarColor` property to customize the colors of different taskbars in the exported PDF document, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Navigations -@using Syncfusion.PdfExport - - - - - - - - - - - -@code { - private List TaskCollection { get; set; } - private SfGantt Gantt; - private List toolbarItem = new List() { new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "PDF Export", TooltipText = "PDF Export", Id = "PdfExport", PrefixIcon = "e-pdfexport" } }; - protected override void OnInitialized() - { - this.TaskCollection = GetTaskCollection(); - } - public async void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) - { - if (args.Item.Id == "PdfExport") - { - GanttPdfExportProperties pdfExport = new GanttPdfExportProperties(); - pdfExport.Style = new PdfGanttStyle(); - pdfExport.Style.TaskbarColor = new PdfTaskbarColor(); - pdfExport.Style.TaskbarColor.ParentTaskbarColor = new PdfColor(220, 118, 51); - pdfExport.Style.TaskbarColor.ParentProgressColor = new PdfColor(203, 67, 53); - pdfExport.Style.TaskbarColor.ChildProgressColor = new PdfColor(35, 155, 86); - pdfExport.Style.TaskbarColor.ChildTaskbarColor = new PdfColor(130, 224, 170); - pdfExport.Style.TaskbarColor.CriticalPathTaskbarColor = new PdfColor(173, 121, 64); - pdfExport.Style.TaskbarColor.CriticalPathProgressColor = new PdfColor(145, 76, 0); - pdfExport.Style.TaskbarColor.BaselineColor = new PdfColor(179, 38, 30); - pdfExport.Style.TaskbarColor.MilestoneColor = new PdfColor(141, 124, 187); - await Gantt.ExportToPdfAsync(pdfExport); - } - } - - public class TaskData - { - public int TaskID { get; set; } - public string TaskName { get; set; } - public DateTime? BaselineStartDate { get; set; } - public DateTime? BaselineEndDate { get; set; } - public DateTime StartDate { get; set; } - public DateTime? EndDate { get; set; } - public string Duration { get; set; } - public int Progress { get; set; } - public int? ParentID { get; set; } - } - - public static List GetTaskCollection() - { - List Tasks = new List() - { - new TaskData() { TaskID = 1, TaskName = "Project initiation", BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 04), StartDate = new DateTime(2021, 04, 02), EndDate = new DateTime(2021, 04, 08) }, - new TaskData() { TaskID = 2, TaskName = "Identify site location", StartDate = new DateTime(2021, 04, 02), EndDate = new DateTime(2021, 04, 02), Duration = "0", BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 02), Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2021, 04, 02), Duration = "5", Progress = 40, BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 06), ParentID = 1 }, - new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2021, 04, 08), Duration = "0", EndDate = new DateTime(2021, 04, 08), BaselineStartDate = new DateTime(2021, 04, 08), BaselineEndDate = new DateTime(2021, 04, 08), Progress = 30, ParentID = 1 }, - new TaskData() { TaskID = 5, TaskName = "Project initiation", StartDate = new DateTime(2021, 04, 02), EndDate = new DateTime(2021, 04, 08) }, - new TaskData() { TaskID = 6, TaskName = "Identify site location", StartDate = new DateTime(2021, 04, 02), Duration = "2", Progress = 30, ParentID = 5, BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 02) }, - new TaskData() { TaskID = 7, TaskName = "Perform soil test", StartDate = new DateTime(2021, 04, 02), Duration = "4", Progress = 40, ParentID = 5, BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 03) }, - new TaskData() { TaskID = 8, TaskName = "Soil test approval", StartDate = new DateTime(2021, 04, 02), Duration = "5", Progress = 30, ParentID = 5, BaselineStartDate = new DateTime(2021, 04, 02), BaselineEndDate = new DateTime(2021, 04, 04) } - }; - return Tasks; - } -} - -{% endhighlight %} -{% endtabs %} - -{% previewsample "https://blazorplayground.syncfusion.com/embed/BXVyijDKBofOIgSk?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} - -### Through event - -The PDF export functionality allows you to customize the appearance of taskbars in the exported PDF document using the [PdfQueryTaskbarInfo](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_PdfQueryTaskbarInfo) event. This event provides the flexibility to customize and format the appearance of taskbars, including parent taskbars, individual taskbars, and milestone templates. - -The following code snippet demonstrates how to use the `PdfQueryTaskbarInfo` event to customize the appearance of taskbars in the exported PDF document, - -{% tabs %} -{% highlight razor tabtitle="Index.razor" %} - -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Grids -@using Syncfusion.Blazor.Navigations -@using Syncfusion.PdfExport - - - - - - - - - - - - - - - @code { private List TaskCollection { get; set; } private SfGantt Gantt; @@ -1235,21 +44,7 @@ The following code snippet demonstrates how to use the `PdfQueryTaskbarInfo` eve await Gantt.ExportToPdfAsync(); } } - public void PdfQueryTaskbarInfoHandler(PdfQueryTaskbarInfoEventArgs args) - { - if (args.Data.TaskID == 3) - { - args.TaskbarStyle.Color = new PdfTaskbarColor(); - args.TaskbarStyle.Color.ChildProgressColor = new Syncfusion.PdfExport.PdfColor(103, 80, 164); - args.TaskbarStyle.Color.ChildTaskbarColor = new Syncfusion.PdfExport.PdfColor(141, 124, 187); - } - if (args.Data.TaskID == 4) - { - args.TaskbarStyle.Color = new PdfTaskbarColor(); - args.TaskbarStyle.Color.MilestoneColor = new Syncfusion.PdfExport.PdfColor(103, 80, 164); - } - - } + public class TaskData { public int TaskID { get; set; } @@ -1282,15 +77,20 @@ The following code snippet demonstrates how to use the `PdfQueryTaskbarInfo` eve {% endhighlight %} {% endtabs %} -{% previewsample "https://blazorplayground.syncfusion.com/embed/VDheittqhyxNSXIj?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} +{% previewsample "https://blazorplayground.syncfusion.com/embed/rZLIsjZgrAtEMygE?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Events triggered during exporting -When exporting the Gantt chart to a PDF document, a series of events are triggered in a specific order, allowing for advanced customization of the export process. Understanding this flow is essential to control and modify the exported content effectively. Below is the flow of events that occur during PDF export in the Gantt chart: +When exporting the Gantt chart to a PDF document, a series of events are triggered in a specific order, allowing for advanced customization of the export process. Understanding this flow is essential for effectively controlling and modifying the exported content. Below is the sequence of events that occur during PDF export in the Gantt chart: * [PdfExporting](https://blazor.syncfusion.com/documentation/gantt-chart/events) + * [PdfQueryTimelineCellInfo](https://blazor.syncfusion.com/documentation/gantt-chart/events) + * [PdfColumnHeaderQueryCellInfo](https://blazor.syncfusion.com/documentation/gantt-chart/events) + * [PdfQueryCellInfo](https://blazor.syncfusion.com/documentation/gantt-chart/events) + * [PdfQueryTaskbarInfo](https://blazor.syncfusion.com/documentation/gantt-chart/events) -* [PdfExported](https://blazor.syncfusion.com/documentation/gantt-chart/events) + +* [PdfExported](https://blazor.syncfusion.com/documentation/gantt-chart/events) \ No newline at end of file diff --git a/blazor/gantt-chart/predecessor-validation.md b/blazor/gantt-chart/predecessor-validation.md index 2970c25c46..5aa126c2d9 100644 --- a/blazor/gantt-chart/predecessor-validation.md +++ b/blazor/gantt-chart/predecessor-validation.md @@ -9,7 +9,7 @@ documentation: ug # Predecessor Validation -By default, Gantt tasks date values are validated based on predecessor values. You can disable/enable this validation by using the [EnablePredecessorValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_EnablePredecessorValidation) property. By default, `EnablePredecessorValidation` is true. +By default, Gantt task date values are validated based on predecessor values. You can enable or disable this validation by using the [EnablePredecessorValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_EnablePredecessorValidation) property. By default, `EnablePredecessorValidation` is **true**. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -68,22 +68,22 @@ By default, Gantt tasks date values are validated based on predecessor values. Y ## Custom validation using TaskbarEditing event -In Gantt, the task relationship link can be broken by editing the start date, end date, and duration value of task. When the task relationship is broken on any edit action, it can be handled in Gantt in the following ways. +In Gantt Chart, the task relationship link can be broken by editing the start date, end date, or duration of a task. When the task relationship is broken during any edit action, it can be handled in Gantt Chart in the following ways. ### Validation mode -When editing the tasks with predecessor links, then the [TaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_TaskbarEditing) event will be triggered. You can validate the editing action within the `TaskbarEditing` event using the [ValidateMode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ValidateMode.html) event argument. The `ValidateMode` event argument has the following properties: +When editing tasks with predecessor links, the [TaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_TaskbarEditing) event is triggered. You can validate the editing action within the `TaskbarEditing` event using the [ValidateMode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ValidateMode.html) event argument. The `ValidateMode` argument provides the following properties: Argument |Default value |Description -----|-----|----- args.ValidateMode.RespectLink | false | In this validation mode, the predecessor links get high priority. For example, in FS type, with this mode enabled, when the successor task is moved before the predecessor task’s end date, the editing will be reverted, and dates will be validated based on the dependency links. args.ValidateMode.PreserveLinkWithEditing | true | In this validation mode, the taskbar editing will be considered along with the dependency links. This relationship will be maintained by updating the offset value of predecessors. -By default, the `PreserveLinkWithEditing` validation mode will be enabled, so the predecessors are updated with offset values. +By default, the [PreserveLinkWithEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ValidateMode.html#Syncfusion_Blazor_Gantt_ValidateMode_PreserveLinkWithEditing) validation mode is enabled, so the predecessors are updated with offset values. ![Blazor Gantt Chart updating offset on edit actions](images/blazor-gantt-chart-preserve-link-with-editing.gif) -The following code example explains enabling the `RespectLink` validation mode while editing the linked tasks in the `TaskbarEditing` event. +The following code example explains enabling the [RespectLink](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ValidateMode.html#Syncfusion_Blazor_Gantt_ValidateMode_RespectLink) validation mode while editing the linked tasks in the [TaskbarEditing](https://blazor.syncfusion.com/documentation/gantt-chart/events#taskbarediting) event. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -144,8 +144,9 @@ The following code example explains enabling the `RespectLink` validation mode w ### Predecessor offset validation -On taskbar editing, the [TaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_TaskbarEditing) event will be triggered with [EnablePredecessorOffsetValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.TaskbarEditingEventArgs-1.html#Syncfusion_Blazor_Gantt_TaskbarEditingEventArgs_1_EnablePredecessorOffsetValidation) argument. When `EnablePredecessorOffsetValidation` is enabled, the taskbar can be dragged such that it does not violate the predecessor value. -The taskbar can be dragged above the given predecessor offset value and it gets reverted to the minimum predecessor value if dragged below the predecessor offset value. +When editing a taskbar, the [TaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_TaskbarEditing) event is triggered with the [EnablePredecessorOffsetValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.TaskbarEditingEventArgs-1.html#Syncfusion_Blazor_Gantt_TaskbarEditingEventArgs_1_EnablePredecessorOffsetValidation) argument. When `EnablePredecessorOffsetValidation` is enabled, the taskbar can be dragged without violating the predecessor offset value. + +The taskbar can be moved above the specified predecessor offset value, but if it is dragged below the offset value, it will revert to the minimum predecessor value. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -212,9 +213,9 @@ N> When `EnablePredecessorOffsetValidation` is enabled, the predecessor offset w ### Auto-link validation -When the connector lines are drawn between tasks, the task date gets validated based on predecessor values. You can restrict this validation on predecessor drawing using the [TaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_TaskbarEditing) event. You can enable/disable the validation using [EnablePredecessorValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.TaskbarEditingEventArgs-1.html#Syncfusion_Blazor_Gantt_TaskbarEditingEventArgs_1_EnablePredecessorValidation) event argument. By default, `EnablePredecessorValidation` is true. +When connector lines are drawn between tasks, the task dates are validated based on predecessor values. You can restrict this validation when drawing predecessors by using the [TaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_TaskbarEditing) event. You can enable or disable the validation using the [EnablePredecessorValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.TaskbarEditingEventArgs-1.html#Syncfusion_Blazor_Gantt_TaskbarEditingEventArgs_1_EnablePredecessorValidation) event argument. By default, `EnablePredecessorValidation` is **true**. -In the below code example, the connector line which is connected from task id 2 to task id 3 is rendered at load time. Hence validation happens. Whereas, the connector line from task id 6 to task id 7 is drawn dynamically and validation is restricted here by disabling the `EnablePredecessorValidation` property. +In the following code example, the connector line connected from task ID 2 to task ID 3 is rendered at load time, so validation occurs. However, the connector line from task ID 6 to task ID 7 is drawn dynamically, and validation is restricted by disabling the `EnablePredecessorValidation` property. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -276,4 +277,4 @@ In the below code example, the connector line which is connected from task id 2 {% previewsample "https://blazorplayground.syncfusion.com/embed/rNBICtjghxOULcTL?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -N> [EnablePredecessorValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_EnablePredecessorValidation) API is used to enable/disable validation based on predecessor values both on load time and on edit actions like cell editing, dialog editing, and on predecessor drawing. Whereas, [EnablePredecessorValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.TaskbarEditingEventArgs-1.html#Syncfusion_Blazor_Gantt_TaskbarEditingEventArgs_1_EnablePredecessorValidation) event argument is used to enable/disable validation only on predecessor drawing. \ No newline at end of file +> [EnablePredecessorValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_EnablePredecessorValidation) API is used to enable/disable validation based on predecessor values both on load time and on edit actions like cell editing, dialog editing, and on predecessor drawing. Whereas, [EnablePredecessorValidation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.TaskbarEditingEventArgs-1.html#Syncfusion_Blazor_Gantt_TaskbarEditingEventArgs_1_EnablePredecessorValidation) event argument is used to enable/disable validation only on predecessor drawing. \ No newline at end of file diff --git a/blazor/gantt-chart/resource-view.md b/blazor/gantt-chart/resource-view.md index 11d5a618c2..a0b1c43c76 100644 --- a/blazor/gantt-chart/resource-view.md +++ b/blazor/gantt-chart/resource-view.md @@ -1,7 +1,7 @@ --- layout: post title: Resource View in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Resource view in Syncfusion Blazor Gantt Chart component and more. +description: Learn how to configure resource view in the Syncfusion Blazor Gantt Chart component for hierarchical task visualization and resource allocation. platform: Blazor control: Gantt Chart documentation: ug @@ -9,7 +9,13 @@ documentation: ug # Resource view in Blazor Gantt Chart Component -To visualize tasks assigned to each resource in a hierarchical manner, you can set the [ViewType](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ViewType) property to [ResourceView](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ViewType.html#Syncfusion_Blazor_Gantt_ViewType_ResourceView) during initialization of the Gantt Chart. This view represents resources as parent records and their corresponding tasks as child records. You can refer to this [link](https://blazor.syncfusion.com/documentation/gantt-chart/resources.html) for detailed instructions on binding resources data within a Gantt Chart. +The resource view in the Blazor Gantt Chart component organizes tasks hierarchically by resource, displaying resources as parent nodes and their assigned tasks as child taskbars in a timeline. Enabled by setting [ViewType](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ViewType) property to [ResourceView](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ViewType.html#Syncfusion_Blazor_Gantt_ViewType_ResourceView), this view visualizes workloads, such as multiple tasks per resource, with taskbars showing duration, progress, and dependencies. Unassigned tasks group under an **Unassigned Task** node. Taskbars include ARIA labels for accessibility, ensuring screen reader compatibility, and adapt to responsive designs, though narrow screens may truncate resource names. Parent tasks are not supported, and tasks require scheduling (start date and duration). + +## Configure resource view + +Enable resource view by setting [ViewType](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ViewType) property to [ResourceView](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ViewType.html#Syncfusion_Blazor_Gantt_ViewType_ResourceView) and mapping resources via [GanttResource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html) and [GanttAssignmentFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html). + +The following example configures resource view: {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -143,15 +149,17 @@ namespace BlazorGanttChart.Data {% previewsample "https://blazorplayground.syncfusion.com/embed/rZVyCDZqqMPafknB?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} +This configuration groups tasks by resources, displaying them as child nodes. + > * In the resource view, records are ordered based on the assigning of task resources. If a task does not have any assigned resources, it is placed under the **Unassigned Tasks** parent record. > * The delete operation in the resource view functions differently: if you delete any task under a resource, the task is first moved under the **Unassigned Tasks** parent record. If you subsequently delete the same record again, it is completely removed from the task collection. > * There is not support for Indent/Outdent in resource view Gantt Chart. -## Resource overallocation +## Visualize resource overallocation -When a resource is assigned more work than they can complete within their available time in a day, it is referred to as overallocation. The available working time for resources to complete tasks in a day is calculated based on the [GanttDayWorkingTime](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttDayWorkingTimeCollection.html#Syncfusion_Blazor_Gantt_GanttDayWorkingTimeCollection_DayWorkingTime) property and the [resource unit](https://blazor.syncfusion.com/documentation/gantt-chart/resources.html#resource-unit). +Overallocation occurs when tasks exceed a resource’s daily capacity, calculated from [GanttDayWorkingTime](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttDayWorkingTimeCollection.html#Syncfusion_Blazor_Gantt_GanttDayWorkingTimeCollection_DayWorkingTime) and [resource unit](https://blazor.syncfusion.com/documentation/gantt-chart/resources.html#resource-unit). Enable indicators with [ShowOverallocation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ShowOverallocation) set to **true** (default: **false**), highlighting affected date ranges with square brackets. -You can indicate overallocation date ranges with square brackets by enabling the feature through the [ShowOverallocation](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ShowOverallocation) property. +The following example toggles overallocation visibility: {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -285,9 +293,11 @@ namespace BlazorGanttChart.Data {% previewsample "https://blazorplayground.syncfusion.com/embed/VjBesjDUULLCVRCX?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -## Unassigned task +## Manage unassigned tasks + +Tasks not assigned to any resource are termed unassigned tasks. These tasks are automatically grouped under a node labeled **Unassigned Task** and displayed at the bottom of the Gantt data collection. -Unassigned tasks in the Gantt Chart refer to tasks that have not been assigned to any particular resource. These tasks are categorized under the parent row **Unassigned Tasks** and appears at the bottom of the Gantt Chart's data collection. +When a resource is subsequently assigned to an unassigned task, the task automatically moves to become a child of the respective resource node. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -598,9 +608,7 @@ namespace BlazorGanttChart.Data ## Taskbar drag and drop between resources -You can smoothly move taskbars vertically, enabling the seamless transfer of tasks between different resources. This capability simplifies task scheduling and enhances overall resource management. Whether you're reassigning tasks to different resources or optimizing resource allocation, you can achieve these tasks effortlessly. - -Within the Gantt chart, taskbar repositioning tasks among different resources can be enabled by setting the [AllowTaskbarDragAndDrop](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskbarSettings.html#Syncfusion_Blazor_Gantt_GanttTaskbarSettings_AllowTaskbarDragAndDrop) property within `GanttTaskbarSettings` to **true**. +Enable taskbar drag-and-drop between resources with [AllowTaskbarDragAndDrop](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskbarSettings.html#Syncfusion_Blazor_Gantt_GanttTaskbarSettings_AllowTaskbarDragAndDrop) set to **true**. This allows vertical taskbar movement for reassignment, triggered by the [RowDragStarting](https://blazor.syncfusion.com/documentation/gantt-chart/events#rowdragstarting) and [RowDropping](https://blazor.syncfusion.com/documentation/gantt-chart/events#rowdropped) events. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -1079,7 +1087,8 @@ namespace BlazorGanttChart.Data ## Limitations -* The resource view in the Gantt Chart does not support assigning multiple resources to a single task. +* Resource view does not support parent tasks; all tasks must be child tasks under resources or the **Unassigned Task** node. +* Unscheduled tasks (lacking start date or duration) are not supported in resource view. * Editing of resource records(parent record) is not supported in the resource view of the Gantt Chart. * CRUD operations are not supported when the [TaskMode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_TaskMode) is set to [Manual](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ScheduleMode.html#Syncfusion_Blazor_Gantt_ScheduleMode_Manual) or [Custom](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ScheduleMode.html#Syncfusion_Blazor_Gantt_ScheduleMode_Custom) in the resource view. @@ -1087,6 +1096,5 @@ namespace BlazorGanttChart.Data * [Resource Unit](https://blazor.syncfusion.com/documentation/gantt-chart/resources.html#resource-unit) * [Configure task duration using Work](https://blazor.syncfusion.com/documentation/gantt-chart/work) -* [Custom taskbar styling using template](https://blazor.syncfusion.com/documentation/gantt-chart/resources.html#binding-data-source-for-resource-collection-and-assigning-resource-to-tasks) - +* [Custom taskbar styling using template](https://blazor.syncfusion.com/documentation/gantt-chart/resources.html#binding-data-source-for-resource-collection-and-assigning-resource-to-tasks) diff --git a/blazor/gantt-chart/resources.md b/blazor/gantt-chart/resources.md index a26dae3df2..6a71d9a4b5 100644 --- a/blazor/gantt-chart/resources.md +++ b/blazor/gantt-chart/resources.md @@ -1,7 +1,7 @@ --- layout: post title: Resources in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Resources in Syncfusion Blazor Gantt Chart component and much more. +description: Learn how to configure resources in the Syncfusion Blazor Gantt Chart component for task allocation and utilization visualization. platform: Blazor control: Gantt Chart documentation: ug @@ -9,17 +9,30 @@ documentation: ug # Resources in Blazor Gantt Chart Component -In [Blazor Gantt Chart](https://www.syncfusion.com/blazor-components/blazor-gantt-chart), the resources are represented by staff, equipment, materials, and so on. It allows for the allocation of resources, such as human resources, to each task. +Resources in the Angular Gantt component represent people, equipment, or materials allocated to tasks, visualized in taskbars and labels for clear utilization tracking. Assigned via the [GanttResource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html) property, resources map to tasks using [GanttAssignmentFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html) for ID, name, unit, and group. This enables display of resource names in columns or labels with [GanttLabelSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttLabelSettings-1.html), highlighting workloads and overallocation. Resources include ARIA labels for accessibility, ensuring screen reader compatibility, and adapt to responsive designs, though narrow screens may truncate names for multiple assignments. By default, resources allocate 100% unit if unspecified. -## Binding data source for resource collection and assigning resource to tasks +## Configure Resource Collection -Resources are a list of `TResources` objects, mapped to the Gantt Chart component using the [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_DataSource) property in [GanttResource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html). To link the resource collection with task collection, the [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_DataSource) property of the [GanttAssignmentFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html) component is essential to use. It is crucial to structure this collection thoughtfully to establish a strong foreign key relationship. This involves linking the [TaskID](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_TaskID) and [ResourceID](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_ResourceID) properties of `GanttAssignmentFields` with the [ID](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Id) property value of [GanttTaskFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html) for tasks and the [Id](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_Id) property of `GanttResource` for resources. +The resource collection in Blazor Gantt Chart defines available resources as a list of objects with fields such as ID, Name, MaxUnits, and Group. These fields are mapped using the [GanttResource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html) property: -Also, the following properties of `GanttResource` component needs to be configured -1. [Name](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_Name) - Maps the resource name -2. [MaxUnits](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_MaxUnits) - resource’s maximum capacity or availability per day. +* [Id](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_Id): Maps to a unique identifier for resource assignment. +* [Name](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_Name): Maps to the resource name displayed in labels or columns. +* [MaxUnits](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_MaxUnits): Maps to the work capacity percentage (0–100%) per day. +* [Group](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_Group): Maps to categories for grouping resources. -The following code snippets show resource collection and how it is assigned to the Gantt Chart component. +The following code demonstrates resource collection setup: + +```cs + +``` + +This configuration maps resources for assignment and display. + +## Assign resources to tasks + +Resources are represented as a list of `TResources` objects and mapped to the Gantt Chart component using the [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_DataSource) property in [GanttResource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html). To link the resource collection with the task collection, you must configure the [DataSource](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_DataSource) property of the [GanttAssignmentFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html) component. It is important to structure this collection carefully to establish a strong foreign key relationship. This involves mapping the [TaskID](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_TaskID) and [ResourceID](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_ResourceID) properties of `GanttAssignmentFields` to the [Id](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Id) property of [GanttTaskFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html) for tasks and the [Id](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_Id) property of `GanttResource` for resources. + +The following code snippets show the resource collection and how it is assigned to the Gantt Chart component. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -163,9 +176,14 @@ namespace BlazorGanttChart.Data ## Resource unit +When defining the resource unit within the resource collection, it specifies the amount of work a resource performs per day for a task. This concept is represented by the [Units](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_Units) property in [GanttAssignmentFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html) and the [MaxUnits](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_MaxUnits) property in `GanttResource`. + +* **Units**: Defines the work amount done per day by a resource for a specific task. +* **MaxUnits**: Sets the resources maximum capacity or availability for any task. + When defining the resource unit within the resource collection, it indicates the amount of work that a specific resource will perform per day for a task. This concept is reflected in both the [Units](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_Units) property in `GanttAssignmentFields` and the [MaxUnits](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResource-2.html#Syncfusion_Blazor_Gantt_GanttResource_2_MaxUnits) property in `GanttResource`. The `Units` property specifies the work amount done per day by a resource for a task, while `MaxUnits` sets the resource's maximum capacity or availability for any task. -To illustrate this concept, the following code snippet demonstrates how to assign resources to specific tasks and map them in the Gantt chart, providing a clear overview of how resource units and maximum capacities are managed in task allocation. For more detailed information about work and resource units, you can refer to the [link](https://blazor.syncfusion.com/documentation/gantt-chart/work). +The following code snippet demonstrates how to assign resources to tasks and map them in the Gantt Chart, providing a clear overview of how resource units and maximum capacities are managed in task allocation. For more details about work and resource units, refer to the [documentation](https://blazor.syncfusion.com/documentation/gantt-chart/work). {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -309,13 +327,12 @@ namespace BlazorGanttChart.Data ## Managing resources assignments in project view -In the Gantt Chart, you can enable dynamic resources assignments by setting the [AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowEditing) properties to **true** in the [GanttEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html) component. These actions can be performed using the following three methods: +In the Gantt Chart, you can enable dynamic resource assignments by setting the [AllowEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowEditing) property to **true** in the [GanttEditSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html) component. These actions can be performed using the following three methods: ### Through cell edit To edit resources directly through [cell editing](https://blazor.syncfusion.com/documentation/gantt-chart/editing-tasks#cell-editing), you can use the [GanttResourceColumn](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttResourceColumn.html) within the [GanttColumns](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttColumns.html) of the Blazor Gantt Chart. The following code snippet demonstrates the cell edit functionality in the Gantt chart. - {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -458,7 +475,7 @@ namespace BlazorGanttChart.Data ### Through dialog box -In the resource tab of the [add/edit dialog box](https://blazor.syncfusion.com/documentation/gantt-chart/editing-tasks#dialog-editing) within the Gantt chart, resources can be conveniently added or removed using the checkboxes provided in the grid rows of the resource tab. Clicking on a checkbox item in a grid row adds the corresponding resource to the task, while unchecking it removes the resource. Also, the resource tab allows editing the unit value for individual resources. +In the resource tab of the [Add/Edit dialog box](https://blazor.syncfusion.com/documentation/gantt-chart/editing-tasks#dialog-editing) within the Gantt chart, resources can be conveniently added or removed using the checkboxes provided in the grid rows of the resource tab. Selecting a checkbox item in a grid row adds the corresponding resource to the task, while unchecking it removes the resource. Additionally, the resource tab allows editing the unit value for individual resources. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -607,7 +624,7 @@ namespace BlazorGanttChart.Data ### Through method -You can manipulate task resources programmatically by using the following methods: +You can manage task resources programmatically by using the following methods: * [AddResourceAssignmentAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AddResourceAssignmentAsync__1___0_): This method adds a new resource to a specific task in the Gantt chart. * [DeleteResourceAssignmentAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_DeleteResourceAssignmentAsync__1___0_): Use this method to remove a resource from an existing task in the Gantt chart. @@ -616,9 +633,10 @@ You can manipulate task resources programmatically by using the following method Additionally, you can retrieve assigned resources and resource assignments through the following methods: * [GetResources](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_GetResources__1__0_): Retrieves the list of resources. + * [GetResourceAssignments](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_GetResourceAssignments__1__0_): Retrieves the list of resource assignments. -* [AddRecordAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AddRecordAsync__0_System_Nullable_System_Int32__System_Nullable_Syncfusion_Blazor_Gantt_RowPosition__System_Object_) - This method is utilized to add a new task to the Gantt chart. The fourth argument in this method is used for adding resources to the task. +* [AddRecordAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AddRecordAsync__0_System_Nullable_System_Int32__System_Nullable_Syncfusion_Blazor_Gantt_RowPosition__System_Object_) - This method is used to add a new task to the Gantt chart. The fourth argument in this method is used for adding resources to the task. These methods offer a convenient way to add, remove, and update task resources in your Gantt chart efficiently. In the code snippet below, upon clicking an external button, the following actions are performed: @@ -813,9 +831,9 @@ namespace BlazorGanttChart.Data ## Resource event -The [ResourceAssignmentChanging](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_ResourceAssignmentChanging) event is triggered in the Blazor Gantt chart when resource add, remove, and update actions occur. This event allows for custom actions to be performed, and it also provides the ability to cancel add, remove, or update actions by setting the [Cancel](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ResourceAssignmentChangeEventArgs-1.html#Syncfusion_Blazor_Gantt_ResourceAssignmentChangeEventArgs_1_Cancel) property of the event argument to **true**. +The [ResourceAssignmentChanging](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttAssignmentFields-2.html#Syncfusion_Blazor_Gantt_GanttAssignmentFields_2_ResourceAssignmentChanging) event is triggered in the Blazor Gantt Chart when resources are added, removed, or updated. This event allows you to perform custom actions and provides the ability to cancel these operations by setting the [Cancel](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.ResourceAssignmentChangeEventArgs-1.html#Syncfusion_Blazor_Gantt_ResourceAssignmentChangeEventArgs_1_Cancel) property of the event argument to **true**. -In the code snippet below, the `ResourceAssignmentChanging` event is used to display a customized message when performing resource add, remove, and update actions. Additionally, it prevents resource deletion for the 1st index task. +In the following code snippet, the `ResourceAssignmentChanging` event is used to display a custom message when adding, removing, or updating resources. Additionally, it prevents resource deletion for the 1st index task. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -982,7 +1000,7 @@ namespace BlazorGanttChart.Data ## Custom taskbar styling using template -The taskbar appearance can be customized by using the [TaskbarTemplate](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTemplates-1.html#Syncfusion_Blazor_Gantt_GanttTemplates_1_TaskbarTemplate) property. In the code snippet below, the child tasks are customized based on template context data, with the resource name added inside each child taskbar, and the taskbar colors are changed based on task resources. +The taskbar appearance can be customized by using the [TaskbarTemplate](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTemplates-1.html#Syncfusion_Blazor_Gantt_GanttTemplates_1_TaskbarTemplate) property. In the following code snippet, child tasks are customized based on the template context data. The resource name is added inside each child taskbar, and the taskbar colors are changed based on the assigned resources. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -1184,4 +1202,4 @@ namespace BlazorGanttChart.Data ## See also -* [CRUD operations on tasks](https://blazor.syncfusion.com/documentation/gantt-chart/managing-tasks) \ No newline at end of file +* [CRUD operations on tasks](https://blazor.syncfusion.com/documentation/gantt-chart/managing-tasks) diff --git a/blazor/gantt-chart/scheduling-tasks.md b/blazor/gantt-chart/scheduling-tasks.md index 4ab4baf79b..976ee17d5a 100644 --- a/blazor/gantt-chart/scheduling-tasks.md +++ b/blazor/gantt-chart/scheduling-tasks.md @@ -1,35 +1,42 @@ --- layout: post -title: Scheduling Tasks in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Scheduling Tasks in Syncfusion Blazor Gantt Chart component and more. +title: Task scheduling in Blazor Gantt Chart Component | Syncfusion +description: Learn task scheduling in Syncfusion Blazor Gantt Chart including automatic, manual, custom, and unscheduled tasks, milestones, and duration units. platform: Blazor control: Gantt Chart documentation: ug --- -# Scheduling Tasks in Blazor Gantt Chart Component +# Task scheduling in Blazor Gantt Chart Component -By default, Gantt tasks are validated based on the child tasks with some factors like working time, holidays, weekends, and predecessors. The Gantt provides support for automatic and manual task scheduling modes. It is used to indicate whether the start date and end date of all the tasks will be automatically validated or not. `TaskMode` is the property used to change the schedule mode of a task. +The Gantt provides support for automatic and manual task scheduling modes. It is used to indicate whether the start date and end date of all the tasks will be automatically validated or not. [TaskMode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_TaskMode) is the property used to change the schedule mode of a task. -The Gantt Chart component supports three types of modes. They are: +The Gantt control supports three types of mode. They are: -* `Auto`: All the tasks will be automatically validated. -* `Manual`: All the tasks will be manually validated by the user. -* `Custom`: Tasks will be validated as Auto or Manual based on the value mapped in the data source. +* **Auto**: All the tasks are automatically validate. +* **Manual**: All the tasks are manually validate by the user. +* **Custom**: Both Auto and Manual tasks are render by mapped from data source. -N> The default value of `TaskMode` is `Auto`. +> The default value of [TaskMode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_TaskMode) is **Auto**. ## Automatically scheduled tasks -When the `TaskMode` property is set as `Auto`, the start date and end date of all the tasks in the project will be automatically validated. That is, dates will be validated based on various factors such as working time, holidays, weekends, and predecessors. +When the [TaskMode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_TaskMode) property is set as **Auto**, the start date and end date of all the tasks in the project will be automatically validated. That is, dates are validated based on various factors such as working time, holidays, weekends and predecessors. -```cshtml +In auto scheduling mode, the parent taskbar will be rendered according to the minimum start date and maximum end date of its child records, irrespective of the dates provided to it in the data source. + +If a child task is updated, the parent task’s start and end dates are automatically updated to reflect the changes. The parent task’s progress is also updated based on the progress of its child tasks. Therefore, you cannot edit the parent taskbar's fields such as progress, endDate, as the parent taskbar is generated based on its subtasks. + +The rendering of the parent taskbar in auto-scheduling mode also takes into account the dependencies between tasks. If a child task is dependent on another task, the parent task’s start date and end date will be adjusted accordingly to ensure that the child task is not scheduled to start before its predecessor is completed. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} @using Syncfusion.Blazor.Gantt - + @@ -42,42 +49,50 @@ When the `TaskMode` property is set as `Auto`, the start date and end date of al } public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "2", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "1", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "2", Progress = 30, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "2", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "1", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "2", Progress = 30, ParentID = 5, } }; return Tasks; } } -``` + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BZrSMNCShfHotWhE?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Manually scheduled tasks -When the `TaskMode` property is set as `Manual`, the start date and end date of all the tasks in the project will be the same as given in the data source. That is, dates will not be validated based on factors such as dependencies between tasks, holidays, weekends, working time. You can restrict this mode in predecessor validation alone. That is, you can automatically validate the dates based on predecessor values by enabling the [ValidateManualTasksOnLinking](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ValidateManualTasksOnLinking) property. +When the [TaskMode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_TaskMode) property is set as **Manual**, the start date and end date of all the tasks in the project will be same as given in the data source. That is, dates are not validated based on various factors such as dependencies between tasks, holidays, weekends, working time. + +We can restrict this mode in predecessor validation alone. That is, we can automatically validate the dates based on predecessor values by enabling the [ValidateManualTasksOnLinking](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ValidateManualTasksOnLinking) property. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -90,43 +105,47 @@ When the `TaskMode` property is set as `Manual`, the start date and end date of } public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 08), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 06), Duration = "4", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 06), Duration = "4", Progress = 40, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 07), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 05), Duration = "3", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 01), EndDate = new DateTime(2022, 01, 09), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 06), Duration = "4", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 06), Duration = "4", Progress = 40, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 05), EndDate = new DateTime(2022, 01, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 05), Duration = "3", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, } }; return Tasks; } } -``` -![Blazor Gantt Chart displays Manual Schedule Task](images/blazor-gantt-chart-manual-schedule-task.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VtBosNWSLzYVIouF?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Custom -If you want to use some specific task mode for specific tasks, then you can set the `TaskMode` property as `Custom`. So, the scheduling mode for each task will be mapped from the data source field. The `Boolean` property [GanttTaskFields.Manual](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Manual) is used to map the manual scheduling mode field from the data source. +When the [TaskMode](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_TaskMode) property is set as **Custom**, the scheduling mode for each tasks will be mapped from the data source field. The `Boolean` property [GanttTaskFields.Manual](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html#Syncfusion_Blazor_Gantt_GanttTaskFields_Manual) is used to map the manual scheduling mode field from the data source. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -139,13 +158,13 @@ If you want to use some specific task mode for specific tasks, then you can set } public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } public bool IsManual { get; set; } } @@ -153,55 +172,49 @@ If you want to use some specific task mode for specific tasks, then you can set { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "3", Progress = 30, ParentId = 1, IsManual= true , }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentId = 1, IsManual= true }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "3", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), IsManual= true }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, IsManual= true } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "3", Progress = 30, ParentID = 1, IsManual= true , }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentID = 1, IsManual= true }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "3", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), IsManual= true }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, IsManual= true } }; return Tasks; } } -``` +{% endhighlight %} +{% endtabs %} -![Blazor Gantt Chart with Custom Scheduled Task](images/blazor-gantt-chart-custom-schedule-task.png) +{% previewsample "https://blazorplayground.syncfusion.com/embed/hjLSCjWyVIMRWTuf?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Unscheduled tasks -Unscheduled tasks are planned for a project without any definite schedule dates. The Gantt Chart component supports rendering the unscheduled tasks. You can create or update the tasks with anyone of start date, end date, and duration values or none. You can enable or disable the unscheduled tasks by using the [AllowUnscheduledTasks](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowUnscheduledTasks) property. The following images represent the various types of unscheduled tasks in Gantt Chart. - -### Start date only - -![Blazor Gantt Chart with Start Date Task](images/blazor-gantt-chart-start-date-task.png) - -### End date only +Unscheduled tasks are planned for a project without any definite schedule dates. The Gantt control supports rendering the unscheduled tasks. You can create or update the tasks with anyone of start date, end date, and duration values or none. You can enable or disable the unscheduled tasks by using the [AllowUnscheduledTasks](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowUnscheduledTasks) property. The following images represent the various types of unscheduled tasks in Gantt. -![Blazor Gantt Chart with End Date Task](images/blazor-gantt-chart-end-date-task.png) +Taskbar state |Auto |Manual +-----|-----|----- +`Start Date Only` | ![Blazor Gantt Chart with Start Date Task](images/blazor-gantt-chart-start-date-task.png) | ![Alt text](images/startDate-manual.png) +`End Date Only` | ![Blazor Gantt Chart with End Date Task](images/blazor-gantt-chart-end-date-task.png) | ![Alt text](images/endDate-manual.png) +`Duration Only` | ![Blazot Gantt Chart with Duration Task](images/blazor-gantt-chart-duration-task.png) | ![Alt text](images/duration-manual.png) +`Milestone`| ![Blazor Gantt Chart with Milestone Task](images/blazor-gantt-chart-milestone-task.png) | ![Blazor Gantt Chart with Milestone Task](images/blazor-gantt-chart-milestone-task.png) -### Duration only - -![Blazot Gantt Chart with Duration Task](images/blazor-gantt-chart-duration-task.png) - -### Milestone - -A milestone is a task that has no start and end dates, but it has a duration value of zero. It is represented as follows. - -![Blazor Gantt Chart with Milestone Task](images/blazor-gantt-chart-milestone-task.png) +> A milestone is a task that has no start and end dates, but it has a duration value of zero. ## Define unscheduled tasks in data source You can define the various types of unscheduled tasks in the data source as follows -```cshtml +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + @using Syncfusion.Blazor.Gantt - + @@ -213,45 +226,49 @@ You can define the various types of unscheduled tasks in the data source as foll } public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", Duration = "4", }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 07), }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 08), Progress = 30, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", Duration = "0"} + new TaskData() { TaskID = 1, TaskName = "Project initiation", Duration = "4", }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), Progress = 30, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", Duration = "0"} }; return Tasks; } } -``` -![Blazor Gantt Chart displays Unscheduled Task](images/blazor-gantt-chart-unscheduled-tasks.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/LZhSsXMyhygtBxWx?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -N> If the [AllowUnscheduledTasks](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowUnscheduledTasks) property is set to false, then the Gantt Chart component automatically calculates the scheduled date values with a default value of duration 1 and the project start date is considered as the start date for the task. +> If the [AllowUnscheduledTasks](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowUnscheduledTasks) property is set to **false**, then the Gantt Chart Component automatically calculates the scheduled date values with a default value of duration 1 and the project start date is considered as the start date for the task. ## Working time range -In the Gantt Chart component, working hours in a day for a project can be defined by using the [GanttDayWorkingTime](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttDayWorkingTimeCollection.html#Syncfusion_Blazor_Gantt_GanttDayWorkingTimeCollection_DayWorkingTime) property. Based on the working hours, automatic date scheduling and duration validations for a task are performed. +In the Gantt Chart component, working hours for all days of a project can be defined by using the [GanttDayWorkingTime](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttDayWorkingTimeCollection.html#Syncfusion_Blazor_Gantt_GanttDayWorkingTimeCollection_DayWorkingTime) property. Based on the working hours, automatic date scheduling and duration validations for a task are performed. -The following code snippet explains how to define the working time range for the project in Gantt Chart. +The following code snippet explains how to define the working time range for the project in Gantt. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -270,49 +287,51 @@ The following code snippet explains how to define the working time range for the } public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 23), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "1", Progress = 70, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "1", Progress = 50, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "1", Progress = 50, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 23), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "1", Progress = 70, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "1", Progress = 50, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 04), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "1", Progress = 70, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "1", Progress = 50, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "1", Progress = 50, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 06), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "1", Progress = 70, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "1", Progress = 50, ParentID = 5, } }; return Tasks; } } -``` -The following screenshot shows working time range in Gantt Chart component. +{% endhighlight %} +{% endtabs %} -![Blazor Gantt Chart displays Working Time Range](images/blazor-gantt-chart-working-time-range.png) +{% previewsample "https://blazorplayground.syncfusion.com/embed/hNLeWjiyhepokIyz?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -N>* Individual tasks can lie between any time within the defined working time range of the project. -
    * The [GanttDayWorkingTime](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttDayWorkingTimeCollection.html#Syncfusion_Blazor_Gantt_GanttDayWorkingTimeCollection_DayWorkingTime) property is used to define the working time for the whole project. +>* Individual tasks can lie between any time within the defined working time range of the project. +>* The [GanttDayWorkingTime](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttDayWorkingTimeCollection.html#Syncfusion_Blazor_Gantt_GanttDayWorkingTimeCollection_DayWorkingTime) property is used to define the working time for the whole project. ## Weekend or non-working days -Non-working days/weekends are used to represent the non-productive days in a project. You can exclude the non-working days in a work week using the `WorkWeek` property in Gantt Chart. +Non-working days/weekend are used to represent the non-productive days in a project. You can define the non-working days in a week using the [WorkWeek](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_WorkWeek) property in Gantt. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -324,60 +343,64 @@ Non-working days/weekends are used to represent the non-productive days in a pro } public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 09), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentID = 5, } }; return Tasks; } } -``` -![Changing Work Week Schedule in Blazor Gantt Chart](images/blazor-gantt-chart-change-work-week.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/hjBSsjsoByxMWadO?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -N> By default, Saturdays and Sundays are considered as non-working days/weekend in a project. -
    In the Gantt Chart component, you can make weekend as working day by setting the `IncludeWeekend` property to `true`. +> By default, Saturdays and Sundays are considered as non-working days/weekend in a project. +> In the Gantt control, you can make weekend as working day by setting the [IncludeWeekend](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_IncludeWeekend) property to **true**`. ## Duration unit -In Gantt Chart, the tasks’ duration value can be measured by the following duration units, +In Gantt Chart, the task's duration value can be measured by the following duration units, * Day * Hour * Minute -In Gantt Chart, you can define the duration unit for the whole project by using the [GanttTaskFields.DurationUnit](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_DurationUnit) property. When you define the value for this property, this unit will be applied for all tasks that do not have a duration unit value. And each task in the project can be defined with different duration units and the duration unit of a task can be defined in the following ways, +In Gantt, we can define duration unit for whole project by using [GanttTaskFields.DurationUnit](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_DurationUnit) property, when we defines the value for this property, this unit will be applied for all task which don't has duration unit value. And each task in the project can be defined with different duration units and the duration unit of a task can be defined by the following ways, -* Using `GanttTaskFields.DurationUnit` property, to map the duration unit data source field. +* Using `DurationUnit` property, to map the duration unit data source field. * Defining the duration unit value along with the duration field in the data source. ### Mapping the duration unit field -The following code snippet explains the mapping of duration unit data source field to the Gantt Chart component using the `GanttTaskFields.DurationUnit` property. +The below code snippet explains the mapping of duration unit data source field to the Gantt control using the [GanttTaskFields.DurationUnit](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_DurationUnit) property. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -390,14 +413,14 @@ The following code snippet explains the mapping of duration unit data source fie public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } public string DurationUnit { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } @@ -405,33 +428,37 @@ The following code snippet explains the mapping of duration unit data source fie { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 70, ParentId = 1, DurationUnit = "day" }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 50, ParentId = 1, DurationUnit = "hour" }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "480", Progress = 30, ParentId = 1, DurationUnit = "minute" }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, DurationUnit = "hour" }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, DurationUnit = "day" }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 70, ParentID = 1, DurationUnit = "day" }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 50, ParentID = 1, DurationUnit = "hour" }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "480", Progress = 30, ParentID = 1, DurationUnit = "minute" }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, DurationUnit = "hour" }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, DurationUnit = "day" }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentID = 5, } }; return Tasks; } } -``` -![Blazor Gantt Chart with Duration Unit](images/blazor-gantt-chart-duration-units.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VNBoCNsehHsMykiH?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -N> The default value of the `DurationUnit` property is `day`. +> The default value of the [GanttTaskFields.DurationUnit](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_DurationUnit) property is `day`. ### Defining duration unit along with duration field -Duration units for the tasks can also be defined along with the duration values. The following code snippet explains the duration unit for a task along with duration value, +Duration units for the tasks can also be defined along with the duration values, the below code snippet explains the duration unit for a task along with duration value. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -444,13 +471,13 @@ Duration units for the tasks can also be defined along with the duration values. public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } @@ -458,22 +485,23 @@ Duration units for the tasks can also be defined along with the duration values. { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "3days", Progress = 70, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "12hours", Progress = 50, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "1800minutes", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "480minutes", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3days", Progress = 40, ParentId = 5, }, + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "3days", Progress = 70, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "12hours", Progress = 50, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "1800minutes", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "480minutes", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3days", Progress = 40, ParentID = 5, }, }; return Tasks; } } -``` -![Blazor Gantt Chart with Duration Units](images/blazor-gantt-chart-duration-unit.png) +{% endhighlight %} +{% endtabs %} -N> The edit type of the duration column in Gantt Chart is string, to support editing the duration field along with duration units. +{% previewsample "https://blazorplayground.syncfusion.com/embed/LNheMDCeVHrVxHgU?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} +> The edit type of the duration column in Gantt Chart is string, to support editing the duration field along with duration units. -N> You can refer to our [Blazor Gantt Chart](https://www.syncfusion.com/blazor-components/blazor-gantt-chart) feature tour page for its groundbreaking feature representations. You can also explore our [Blazor Gantt Chart example](https://blazor.syncfusion.com/demos/gantt-chart/default-functionalities?theme=bootstrap5) to know how to render and configure the Gantt. \ No newline at end of file +> You can refer to our [Blazor Gantt Chart](https://www.syncfusion.com/blazor-components/blazor-gantt-chart) feature tour page for its groundbreaking feature representations. You can also explore our [Blazor Gantt Chart example](https://blazor.syncfusion.com/demos/gantt-chart/default-functionalities?theme=bootstrap5) to know how to render and configure the Gantt. diff --git a/blazor/gantt-chart/splitter.md b/blazor/gantt-chart/splitter.md index 0d32efe542..3dbd534410 100644 --- a/blazor/gantt-chart/splitter.md +++ b/blazor/gantt-chart/splitter.md @@ -1,7 +1,7 @@ --- layout: post title: Splitter in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Splitter in Syncfusion Blazor Gantt Chart component and much more details. +description: Learn how to configure the splitter in the Syncfusion Blazor Gantt Chart component for flexible TreeGrid and Chart panel sizing. platform: Blazor control: Gantt Chart documentation: ug @@ -9,15 +9,13 @@ documentation: ug # Splitter in Blazor Gantt Chart Component -## Splitter +The splitter in the Blazor Gantt Chart component divides the TreeGrid (task data table) and Chart (timeline with taskbars) panels, enabling flexible width allocation for project visualization. Configured via the [GanttSplitterSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttSplitterSettings.html) property, the splitter supports pixel or percentage-based positioning, column-based alignment, and predefined view modes. The [SetSplitterPosition](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_SetSplitterPositionAsync_System_Int32_) method adjusts positioning dynamically, while the [SplitterResizeStart](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_SplitterResizeStart), [SplitterResizing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_SplitterResizing), and [SplitterResized](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_SplitterResized) events handle resize interactions. The splitter includes ARIA labels for accessibility, ensuring screen reader compatibility, and adapts to responsive designs, though narrow screens may limit visible columns or timeline segments. By default, both panels are visible with equal width. -Gantt Chart component consists of both Tree Grid part and Chart part. Splitter is used to resize the Tree Grid section from the Chart section. You can change the position of the Splitter when loading the Gantt Chart component using the [SplitterSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttSelectionSettings.html) property. The following list defines possible values for this property: +## Configure splitter position -| **Splitter Properties** | **Description** | -| --- | --- | -| `GanttSplitterSettings.Position` | This property denotes the percentage of the Tree Grid section’s width to be rendered and this property supports both pixels and percentage values | -| `GanttSplitterSettings.ColumnIndex` | This property defines the splitter position as column index value | -| `GanttSplitterSettings.View` | * `Default`: Shows Grid side and Gantt Chart side.
    * `Grid`: Shows Grid side alone in Gantt Chart.
    * `Chart`: Shows chart side alone in Gantt Chart. | +Set the splitter position using [GanttSplitterSettings.Position](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttSplitterSettings.html#Syncfusion_Blazor_Gantt_GanttSplitterSettings_Position) with pixel (e.g., "300px") or percentage (e.g., "30%") values to define the TreeGrid pane width, or align to a column edge with [GanttSplitterSettings.ColumnIndex](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttSplitterSettings.html#Syncfusion_Blazor_Gantt_GanttSplitterSettings_ColumnIndex). + +The following example sets a percentage-based splitter position. This configuration allocates 80% width to the TreeGrid panel. {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -71,11 +69,11 @@ Gantt Chart component consists of both Tree Grid part and Chart part. Splitter i {% previewsample "https://blazorplayground.syncfusion.com/embed/rtBIWNNaArlKXynp?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -## Change splitter position dynamically +## Adjust splitter position dynamically -In Gantt Chart, you can change the splitter position dynamically by using `SetSplitterPositionAsync` method. You can change the splitter position by passing value and type parameter to `SetSplitterPositionAsync` method. Type parameter will accept one of the following values 'Position', 'ColumnIndex', 'ViewType'. +Change the splitter position using the [SetSplitterPositionAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_SetSplitterPositionAsync_System_Int32_) method with pixel, percentage, or column index values, triggered by events like window resizing or button clicks. -The following code example shows how to use this method. +The following example adjusts the splitter dynamically: {% tabs %} {% highlight razor tabtitle="Index.razor" %} @@ -168,4 +166,4 @@ The following code example shows how to use this method. {% endhighlight %} {% endtabs %} -{% previewsample "https://blazorplayground.syncfusion.com/embed/rZVoiXXaAhuibSQZ?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} +{% previewsample "https://blazorplayground.syncfusion.com/embed/rZVoiXXaAhuibSQZ?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} \ No newline at end of file diff --git a/blazor/gantt-chart/taskbar-editing.md b/blazor/gantt-chart/taskbar-editing.md index db821c7d04..04cf8dbaac 100644 --- a/blazor/gantt-chart/taskbar-editing.md +++ b/blazor/gantt-chart/taskbar-editing.md @@ -1,7 +1,7 @@ --- layout: post title: Taskbar editing in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Taskbar editing in Syncfusion Blazor Gantt Chart component and more. +description: Learn how to edit tasks via taskbar interactions in the Syncfusion Blazor Gantt Chart component for intuitive project timeline adjustments. platform: Blazor control: Gantt Chart documentation: ug @@ -9,12 +9,14 @@ documentation: ug # Taskbar editing in Blazor Gantt Chart Component -Modify the task details through user interaction, such as resizing and dragging the taskbar, by enabling the [GanttEditSettings.AllowTaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowTaskbarEditing) property. When you begin taskbar editing by clicking on a taskbar, a virtual taskbar appears over it. This virtual taskbar serves as a reference, helping you remember the original position of the task on the timeline before making any changes. With the virtual taskbar as a reference, you can make adjustments to the task, such as changing the duration by resizing the taskbar and dragging the taskbar to the desired position on the timeline to adjust the task's start and end dates. +Task bar editing in the Blazor Gantt Chart component enables intuitive project timeline adjustments by allowing to drag or resize taskbars to modify task details, such as start dates, durations, or progress, using mouse or touch interactions. Enable this feature by setting the [GanttEditSettings.AllowTaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowTaskbarEditing) property to **true**, ensuring task data aligns with valid [GanttTaskFields](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTaskFields.html) mappings (e.g., ID, StartDate, Duration). When taskbar editing begins by clicking or tapping on a taskbar, a virtual taskbar appears over the original. This overlay acts as a reference to indicate the original position of the task on the timeline before any changes are made. With this reference, it is possible to drag the taskbar to shift start and end dates, resize it to adjust durations, or move the progress grip to update completion percentages. The [TaskbarEditing](https://blazor.syncfusion.com/documentation/gantt-chart/events#taskbarediting) event allows preventing edits for specific tasks. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -28,41 +30,47 @@ Modify the task details through user interaction, such as resizing and dragging public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 02), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 02), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 02), Duration = "4", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 02), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 02), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 04), Duration = "3", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 04), Duration = "3", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 04), Duration = "0", Progress = 30, ParentId = 5 } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 04), EndDate = new DateTime(2022, 04, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 04), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 04), Duration = "4", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 04), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 04), EndDate = new DateTime(2022, 04, 21), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 04), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 04), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 04), Duration = "0", Progress = 30, ParentID = 5 } }; return Tasks; } } -``` + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/rjrStaBeqAqlpiUb?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Creating taskbar on draw action -A taskbar can be drawn in an empty row by drag and drop interaction. This can be achieved by enabling the [GanttEditSettings.AllowSchedulingOnDrag](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowSchedulingOnDrag) and [GanttEditSettings.AllowTaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowTaskbarEditing) property. +A taskbar can be drawn in an empty row by drag and drop interaction. This can be achieved by enabling the [GanttEditSettings.AllowSchedulingOnDrag](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowSchedulingOnDrag) and [GanttEditSettings.AllowTaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEditSettings.html#Syncfusion_Blazor_Gantt_GanttEditSettings_AllowTaskbarEditing) properties. A taskbar can be drawn only when [AllowUnscheduledTasks](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_AllowUnscheduledTasks) property is set to true and when a task has no start and end date. -```cshtml +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + @using Syncfusion.Blazor.Gantt - + @@ -76,44 +84,50 @@ A taskbar can be drawn only when [AllowUnscheduledTasks](https://help.syncfusion } public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime? StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2019, 04, 02) }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", EndDate =new DateTime(2019, 04, 03), Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project initiation", StartDate = new DateTime(2019, 04, 04) }, - new TaskData() { TaskId = 6, TaskName = "Identify Site location", StartDate = new DateTime(2019, 04, 02), Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "Perform soil test", StartDate = new DateTime(2019, 04, 02), Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Soil test approval", EndDate = new DateTime(2019, 04, 02), Progress = 30, ParentId = 5 }, - new TaskData() { TaskId=9, TaskName="Marketing and presales", StartDate=new DateTime(2019,06,26), EndDate=new DateTime(2019,07,01) }, - new TaskData() { TaskId = 10, TaskName = "Important improvement", StartDate = new DateTime(2019, 06, 14), EndDate = new DateTime(2019, 06, 19) } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2019, 04, 03) }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", EndDate =new DateTime(2019, 04, 03), Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project initiation", StartDate = new DateTime(2019, 04, 04) }, + new TaskData() { TaskID = 6, TaskName = "Identify Site location", StartDate = new DateTime(2019, 04, 02), Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "Perform soil test", StartDate = new DateTime(2019, 04, 02), Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Soil test approval", EndDate = new DateTime(2019, 04, 02), Progress = 30, ParentID = 5 }, + new TaskData() { TaskID=9, TaskName="Marketing and presales", StartDate=new DateTime(2019,06,26), EndDate=new DateTime(2019,07,01) }, + new TaskData() { TaskID = 10, TaskName = "Important improvement", StartDate = new DateTime(2019, 06, 14), EndDate = new DateTime(2019, 06, 19) } }; return Tasks; } } -``` -![Taskbar draw in Blazor Gantt Chart](./images/taskbar_draw.gif) + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BjrIXOBIqTQEudyf?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Prevent editing for specific tasks On the taskbar edit action, the [TaskbarEditing](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttEvents-1.html#Syncfusion_Blazor_Gantt_GanttEvents_1_TaskbarEditing) event will be triggered. You can prevent the taskbar from editing using the `TaskbarEditing` event. This can be done by setting the [Cancel](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.TaskbarEditingEventArgs-1.html#Syncfusion_Blazor_Gantt_TaskbarEditingEventArgs_1_Cancel) property of the taskbarEditing event argument to true. For more information, refer to the following: -```cshtml + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + @using Syncfusion.Blazor.Gantt - + @@ -122,7 +136,7 @@ For more information, refer to the following: @code{ private void TaskbarBeginEditHandler(TaskbarEditingEventArgs args) { - if(args.Data.TaskId == 3) + if(args.Data.TaskID == 3) args.Cancel = true; } @@ -134,30 +148,34 @@ For more information, refer to the following: public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } public string Predecessor { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2019, 04, 05), EndDate = new DateTime(2019, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2019, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2019, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2019, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2019, 04, 06), EndDate = new DateTime(2019, 04, 21), Predecessor = "1FS", }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2019, 04, 06), Duration = "3", Progress = 30, Predecessor = "4" , ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2019, 04, 06), Duration = "3", Progress = 40, Predecessor = "6" , ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2019, 04, 06), Duration = "0", Progress = 30, Predecessor = "7" , ParentId = 5 }, + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2019, 04, 05), EndDate = new DateTime(2019, 04, 21), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2019, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2019, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2019, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2019, 04, 06), EndDate = new DateTime(2019, 04, 21), Predecessor = "1FS", }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2019, 04, 06), Duration = "3", Progress = 30, Predecessor = "4" , ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2019, 04, 06), Duration = "3", Progress = 40, Predecessor = "6" , ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2019, 04, 06), Duration = "0", Progress = 30, Predecessor = "7" , ParentID = 5 }, }; return Tasks; } } -``` \ No newline at end of file + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/rtBIZkVyqoXNCLAZ?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} \ No newline at end of file diff --git a/blazor/gantt-chart/tool-bar.md b/blazor/gantt-chart/tool-bar.md index 06f4577113..047967f9c6 100644 --- a/blazor/gantt-chart/tool-bar.md +++ b/blazor/gantt-chart/tool-bar.md @@ -1,19 +1,19 @@ --- layout: post title: Toolbar in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Toolbar in Syncfusion Blazor Gantt Chart component and much more details. +description: Learn all about the Toolbar in Syncfusion Blazor Gantt Chart, including customization, actions and more. platform: Blazor -control: Gantt Chart +control: Toolbar documentation: ug --- # Toolbar in Blazor Gantt Chart Component -The Gantt Chart component provides the toolbar support to handle Gantt Chart actions. The [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_Toolbar) property accepts the collection of built-in toolbar items and `ToolbarItem` objects for custom toolbar items. +The Blazor Gantt Chart component includes built-in toolbar support for executing common actions such as editing, searching, and navigating the timeline. The [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_Toolbar) property accepts the collection of built-in toolbar items and `ToolbarItem` objects for custom toolbar items. ## Built-in toolbar items -Built-in toolbar items execute standard actions of the Gantt Chart component, and these items can be added to toolbar by defining the `Toolbar` as a collection of built-in items. It renders the button with icon and text. +Built-in toolbar items allow you to perform standard operations directly from the Gantt interface. These items can be added to the toolbar by specifying the [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_Toolbar) property as a collection of predefined items. Each toolbar item appears as a button with an associated icon and label for intuitive interaction. The following table shows built-in toolbar items and its actions. @@ -35,11 +35,13 @@ The following table shows built-in toolbar items and its actions. | ZoomOut | To perform zoom-out action on Gantt Chart timeline. | | ZoomToFit | To show all tasks with timeline fit into available Chart width. | -```cshtml +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + @using Syncfusion.Blazor.Gantt - + @@ -47,7 +49,7 @@ The following table shows built-in toolbar items and its actions. @code{ - public string[] Searchfields = new string[] { "TaskId", "TaskName", "StartDate", "EndDate", "Duration", "Progress" }; + public string[] Searchfields = new string[] { "TaskID", "TaskName", "StartDate", "EndDate", "Duration", "Progress" }; private List TaskCollection { get; set; } protected override void OnInitialized() { @@ -56,65 +58,73 @@ The following table shows built-in toolbar items and its actions. public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentID = 5, } }; return Tasks; } } -``` -![Blazor Gantt Chart with Default Toolbar](images/blazor-gantt-chart-default-toolbar.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VjhyCNrhgoIEpOJJ?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -N> The `Toolbar` has options to define both built-in and custom toolbar items. +> * The [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_Toolbar) has options to define both built-in and custom toolbar items. ## Custom toolbar items -Custom toolbar items can be added to the toolbar by defining the `Toolbar` property as a collection of `ItemModels`. Actions for this customized toolbar items are defined in the `OnToolbarClick` event. +You can add custom items to the Gantt chart toolbar by setting the [Toolbar](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_Toolbar) property with a collection of `ItemModel` objects. The actions associated with these custom toolbar items can be handled using the [OnToolbarClick](https://blazor.syncfusion.com/documentation/gantt-chart/events#ontoolbarclick) event. -By default, the custom toolbar items are at left position. You can change the position by using the `Align` property. In the following sample, the `Quick Filter` toolbar item is positioned at right. +By default, custom toolbar items are aligned to the left. However, you can change their position using the [Align](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Navigations.ToolbarItem.html#Syncfusion_Blazor_Navigations_ToolbarItem_Align) property. In the example below, the **Collapse All** toolbar item is aligned to the right. -```cshtml -@using Syncfusion.Blazor.Gantt -@using Syncfusion.Blazor.Navigations +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} - + @code{ public SfGantt Gantt; - public List Toolbaritems = new List() { new ToolbarItem() { Text = "Quick Filter", - TooltipText = "Quick Filter", Id = "toolbarfilter" } }; + public List Toolbaritems = new List() + { + new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "Expand All",TooltipText = "Expand All", Id = "ExpandAll" }, + new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "Collapse All",TooltipText = "Collapse All", Id = "CollapseAll", Align = Syncfusion.Blazor.Navigations.ItemAlign.Right } + }; private List TaskCollection { get; set; } - public void ToolbarClickHandler(ClickEventArgs args) + public void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) { - if (args.Item.Id == "toolbarfilter") + if (args.Item.Id == "ExpandAll") { - this.Gantt.FilterByColumnAsync("TaskName", "startswith", "Identify"); + this.Gantt.ExpandAllAsync(); + } + if(args.Item.Id == "CollapseAll") + { + this.Gantt.CollapseAllAsync(); } } @@ -125,65 +135,67 @@ By default, the custom toolbar items are at left position. You can change the po public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentID = 5, } }; return Tasks; } } -``` -N> * The `Toolbar` has options to define both built-in and custom toolbar items. -
    * If a toolbar item does not match the built-in items, it will be treated as a custom toolbar item. +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BNhIWtrBAcHEYwhs?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} -![Alt text](images/customToolbar.png) +> * If a toolbar item does not match the built-in items, it will be treated as a custom toolbar item. ## Built-in and custom items in toolbar -The Gantt Chart component has an option to use both built-in and custom toolbar items at the same time. +The Gantt component supports using both built-in and custom toolbar items simultaneously. In this example, **ExpandAll** and **CollapseAll** are built-in items, while **Test** is a custom item added to the toolbar. -In the following example, the `ExpandAll` and `CollapseAll` are built-in toolbar items and `Test` is the custom toolbar item. +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt @using Syncfusion.Blazor.Navigations - +

    @Message

    - + @code{ public SfGantt Gantt; - public List Toolbaritems = new List() { "ExpandAll", "CollapseAll", new ToolbarItem() { Text = "Test", TooltipText = "Test", Id = "Test" } }; + public List Toolbaritems = new List() { "ExpandAll", "CollapseAll", new Syncfusion.Blazor.Navigations.ToolbarItem() { Text = "Test", TooltipText = "Test", Id = "Test" } }; private List TaskCollection { get; set; } + public string Message; - public void ToolbarClickHandler(ClickEventArgs args) + public void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) { if (args.Item.Id == "Test") { - Console.WriteLine("Custom toolbar click..."); + this.Message = "Custom Toolbar Clicked"; } } @@ -194,54 +206,62 @@ In the following example, the `ExpandAll` and `CollapseAll` are built-in toolbar public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentID = 5, } }; return Tasks; } } -``` -![Customizing Toolbar Items in Blazor Gantt Chart](images/blazor-gantt-chart-with-custom-toolbar.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/LjLyMDLVJigSxqLs?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5 %} ## Enable or disable toolbar items -You can enable or disable the toolbar items by using the `EnableItems` method. +You can control toolbar items dynamically using the [EnableItems](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Navigations.SfToolbar.html#Syncfusion_Blazor_Navigations_SfToolbar_EnableItems_System_Collections_Generic_List_System_Int32__System_Nullable_System_Boolean__) method. This allows you to enable or disable specific items based on user actions or application state. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt @using Syncfusion.Blazor.Navigations +@using Syncfusion.Blazor.Buttons - - +
    + + +
    - + @code{ public SfGantt Gantt; + private bool? isChecked = true; public List Toolbaritems = new List() { new ToolbarItem() { Text = "Quick Filter", TooltipText = "Quick Filter", Id = "quickfilter" }, new ToolbarItem() { Text = "Clear Filter", TooltipText = "Clear Filter", Id = "clearfilter" } }; public void ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args) @@ -255,13 +275,10 @@ You can enable or disable the toolbar items by using the `EnableItems` method. this.Gantt.ClearFilteringAsync(); } } - public void EnableToolbar() - { - this.Gantt.EnableItems(new List() { 0,1 }, true); - } - public void DisableToolbar() + private void OnSwitchChange(Syncfusion.Blazor.Buttons.ChangeEventArgs args) { - this.Gantt.EnableItems(new List() { 0,1 }, false); + this.isChecked = args.Checked; + this.Gantt.EnableItems(new List() { 0, 1 }, isChecked ?? true); } public List TaskCollection { get; set; } protected override void OnInitialized() @@ -271,33 +288,35 @@ You can enable or disable the toolbar items by using the `EnableItems` method. public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } private static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentId = 1, }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentId = 1, }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 17), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentId = 5, }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentId = 5, }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentId = 5, } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 01, 04), EndDate = new DateTime(2022, 01, 07), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 01, 04), Duration = "4", Progress = 40, ParentID = 1, }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 01, 04), Duration = "0", Progress = 30, ParentID = 1, }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 01, 06), EndDate = new DateTime(2022, 01, 10), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 30, ParentID = 5, }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 01, 06), Duration = "3", Progress = 40, ParentID = 5, }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 01, 06), Duration = "0", Progress = 30, ParentID = 5, } }; return Tasks; } } -``` -![Enabling Toolbar Items in Blazor Gantt Chart](images/blazor-gantt-chart-enable-toolbar.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/BZLyiDLTLJawoAQK?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} N> You can refer to our [Blazor Gantt Chart](https://www.syncfusion.com/blazor-components/blazor-gantt-chart) feature tour page for its groundbreaking feature representations. You can also explore our [Blazor Gantt Chart example](https://blazor.syncfusion.com/demos/gantt-chart/default-functionalities?theme=bootstrap5) to know how to render and configure the Gantt. \ No newline at end of file diff --git a/blazor/gantt-chart/top-tier-and-bottom-tier.md b/blazor/gantt-chart/top-tier-and-bottom-tier.md index 95c3d9c4ff..fd54f61599 100644 --- a/blazor/gantt-chart/top-tier-and-bottom-tier.md +++ b/blazor/gantt-chart/top-tier-and-bottom-tier.md @@ -1,25 +1,35 @@ --- layout: post title: Top tier and bottom tier in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Top tier and bottom tier timeline cells in Syncfusion Blazor Gantt Chart component and much more. +description: Learn how to configure top and bottom tiers in the Syncfusion Blazor Gantt Chart component using timeline settings such as unit, format, count, and formatter. platform: Blazor -control: Gantt Chart +control: Top tier and bottom tier documentation: ug --- -# Top tier and bottom tier +# Top tier and bottom tier in Blazor Gantt Chart component -Gantt Chart component contains two tier layout in timeline, you can customize the top tier and bottom tier using [GanttTopTierSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTopTierSettings.html) and [GanttBottomTierSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttBottomTierSettings.html) properties. Timeline tier's unit can be defined by using `Unit` property and `Format` property was used to define date format of timeline cell and `Count` property was used to define how many unit will be combined as single cell. +The Blazor Gantt Chart component supports a two-tier timeline layout, enabling customization of both the top and bottom tiers through specific configuration options. + +- [TopTier](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineSettings_TopTier) and [BottomTier](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineSettings_BottomTier): Define the structure and visibility of each timeline tier. +- [Unit](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Unit): Specifies the time unit for each tier, such as day, week, or month. +- [Format](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Format): Determines the date format displayed in timeline cells. +- [Count](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Count): Combines multiple time units into a single timeline cell. +- [Formatter](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Formatter): Applies a custom method to format the timeline cell values programmatically. + +These properties allow precise control over how time intervals are displayed, enhancing the readability and usability of the Gantt chart across various project scales. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + - + @@ -32,46 +42,55 @@ Gantt Chart component contains two tier layout in timeline, you can customize th public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentId = 5 }, + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 }, }; return Tasks; } } -``` -![Blazor Gantt Chart with Top and Bottom Tier](images/blazor-gantt-chart-top-bottom-tier.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VtrSWXicLfvvejyd?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Combining timeline cells -In Gantt Chart, timeline cells in top tier and bottom tier can be combined with number of timeline units, this can be achieved by using `GanttTopTierSettings.Count` and `GanttBottomTierSettings.Count` properties. Refer the following sample. +In the Blazor Gantt Chart component, timeline cells in the top and bottom tiers can be merged by grouping multiple time units into a single cell. This behavior is controlled using the `Count` property in both `TopTier` and `BottomTier` configurations. + +- [TopTier.count](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Count): Specifies the number of time units to combine in each top-tier cell. +- [BottomTier.count](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Count): Specifies the number of time units to combine in each bottom-tier cell. + +By adjusting these values, the timeline can display broader or more granular intervals, improving visibility for long-term or short-term project views. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + - + @@ -86,42 +105,51 @@ In Gantt Chart, timeline cells in top tier and bottom tier can be combined with public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 08, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify site location", StartDate = new DateTime(2022, 04, 05), Duration = "150", Progress = 70, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "150", Progress = 50, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "150", Progress = 50, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 05, 06), EndDate = new DateTime(2022, 09, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 05, 06), Duration = "150", Progress = 70, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 05, 06), Duration = "150", Progress = 50, ParentId = 5 }, + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 08, 21), }, + new TaskData() { TaskID = 2, TaskName = "Identify site location", StartDate = new DateTime(2022, 04, 05), Duration = "150", Progress = 70, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "150", Progress = 50, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "150", Progress = 50, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 05, 06), EndDate = new DateTime(2022, 09, 21), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 05, 06), Duration = "150", Progress = 70, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 05, 06), Duration = "150", Progress = 50, ParentID = 5 }, }; return Tasks; } } -``` -![Combining Timeline Cells in Blazor Gantt Chart](images/blazor-gantt-chart-combine-cells.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/rXVeMjsmrILGXGvG?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Format value of timeline cell -## Customize header timeline cells +In the Blazor Gantt Chart component, the values displayed in the top and bottom timeline cells can be formatted using either standard date format strings or custom formatter methods. -In the Gantt Chart component, you can format the value of top and bottom timeline cells using the standard date format string or the custom formatter method. This can be done using the `GanttTopTierSettings.Format`, `GanttTopTierSettings.FormatterTemplate`, `GanttBottomTierSettings.Format`, and `GanttBottomTierSettings.FormatterTemplate` properties. The following example shows how to use the formatter method for timeline cells. +- [TopTier.Format](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Format) and [BottomTier.Format](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Format): Define the date format for timeline cells using predefined format strings. +- [TopTier.formatter](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Formatter) and [BottomTier.formatter](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Formatter): Apply custom logic to format timeline cell values programmatically. + +These options provide flexibility in presenting timeline data according to project requirements or localization needs. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -148,13 +176,13 @@ In the Gantt Chart component, you can format the value of top and bottom timelin public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public string Formatter(DateTime? date) { DateTime dateTime=(DateTime)(date); @@ -171,29 +199,42 @@ In the Gantt Chart component, you can format the value of top and bottom timelin } public static List GetTaskCollection() { List Tasks = new List () { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 06, 21) }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "20", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "24", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 05, 05), Duration = "25", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 06, 06), EndDate = new DateTime(2022, 09, 21) }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 06, 06), Duration = "33", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 07, 06), Duration = "23", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 08, 06), Duration = "20", Progress = 30, ParentId = 5 } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 06, 08) }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "20", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "24", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 05, 05), Duration = "25", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 06, 06), EndDate = new DateTime(2022, 09, 02) }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 06, 06), Duration = "33", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 07, 06), Duration = "23", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 08, 06), Duration = "20", Progress = 30, ParentID = 5 } }; return Tasks; } } -``` + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/hZrSsNimUskhhuZd?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Timeline cell width -In the Gantt Chart component, you can define the width value of timeline cell using the `GanttTimelineSettings.TimelineUnitSize` property. This value will be set to the bottom timeline cell, and the width value of top timeline cell will be calculated automatically based on bottom tier cell width using the `GanttTopTierSettings.Unit` and `GanttTimelineSettings.TimelineUnitSize` properties. Refer the following example. +In the Blazor Gantt Chart component, the width of timeline cells can be configured using the [TimelineSettings.TimelineUnitSize](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineSettings_TimelineUnitSize) property within [TimelineSettings](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineSettings.html). This value directly sets the width of the bottom tier cells. + +The width of the top tier cells is automatically calculated based on the bottom tier's unit and the specified `TimelineUnitSize`. This ensures consistent scaling across both tiers while maintaining clarity in the timeline view. + +- [TimelineSettings.TimelineUnitSize](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineSettings_TimelineUnitSize): Defines the pixel width of each bottom-tier timeline cell. +- [TopTier.Unit](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.GanttTimelineTierSettings.html#Syncfusion_Blazor_Gantt_GanttTimelineTierSettings_Unit): Determines how the top-tier cell width is derived relative to the bottom tier. + +This configuration allows precise control over the visual density of the timeline, supporting both detailed and high-level project views. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -207,31 +248,33 @@ In the Gantt Chart component, you can define the width value of timeline cell us public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime? EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentId = 5 } + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, ParentID = 5 } }; return Tasks; } } -``` -![Customizing Timeline Width in Blazor Gantt Chart](images/blazor-gantt-chart-time-line-width.png) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VZBSMZCQKVggEfTc?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} \ No newline at end of file diff --git a/blazor/gantt-chart/zooming.md b/blazor/gantt-chart/zooming.md index 7905c648bf..2f8129e19b 100644 --- a/blazor/gantt-chart/zooming.md +++ b/blazor/gantt-chart/zooming.md @@ -1,32 +1,36 @@ --- layout: post title: Zooming in Blazor Gantt Chart Component | Syncfusion -description: Checkout and learn here all about Zooming timespan levels in Syncfusion Blazor Gantt Chart component and much more. +description: Explore zooming options in the Syncfusion Blazor Gantt Chart component, including Zoom In, Zoom Out, Zoom To Fit, and custom zooming levels. platform: Blazor -control: Gantt Chart +control: Zooming documentation: ug --- -# Zooming in Blazor Gantt Chart Component +# Zooming functionality in Blazor Gantt Chart component -Gantt Chart has 25 predefined zooming timespan levels from year timespan to hour timespan. This support enables you to view the tasks in a project clearly from minute to decade timespan. To enable the zooming features, define the `ZoomIn`, `ZoomOut`, and `ZoomToFit` items to toolbar items collections. The following zooming options are available to view the project: +The Blazor Gantt Chart component provides zooming support to adjust the timeline view dynamically. This includes increasing or decreasing the width of timeline cells and changing the timeline units to view tasks across various timespan from minutes to decades. -## Zoom in +To enable zooming features, add `ZoomIn`, `ZoomOut`, and `ZoomToFit` to the toolbar items collection. These actions can also be triggered externally using the built-in methods like [ZoomIn](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ZoomInAsync), [ZoomOut](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ZoomOutAsync), and [ZoomToFitAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ZoomToFitAsync). + +**Zoom in** This support is used to increase the timeline width and timeline unit from years to minutes timespan. When the `ZoomIn` icon was clicked, the timeline cell width is increased when the cell size exceeds the specified range and the timeline unit is changed based on the current zoom levels. -## Zoom out +**Zoom out** This support is used to increase the timeline width and timeline unit from minutes to years timespan. When the `ZoomOut` icon was clicked, the timeline cell width is decreased when the cell size falls behind the specified range and the timeline view mode is changed based on the current zooming levels. -## Zoom to fit +**Zoom to fit** + +This support is used to view all the tasks available in a project within available area on the chart part of Gantt. When users click the `ZoomToFit` icon, then all the tasks are rendered within the available chart container width. -This support is used to view all the tasks available in a project to specific timespan which is compatible with available area on the chart part of Gantt Chart. When users click the `ZoomToFit` icon, then all the tasks are rendered within the available chart container width. +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -40,48 +44,48 @@ This support is used to view all the tasks available in a project to specific ti public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } public string Predecessor { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentId = 5 }, + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentID = 5 }, }; return Tasks; } } -``` -![Zooming in Blazor Gantt Chart](images/blazor-gantt-chart-zooming.png) +{% endhighlight %} +{% endtabs %} -## Zoom action by methods - -Zooming action also can be performed on external actions such as button click using the `ZoomIn()`, `ZoomOut()`, and `ZoomToFitAsync()` built-in methods. +{% previewsample "https://blazorplayground.syncfusion.com/embed/BXrIMZicUTszPxmp?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Customizing zooming levels -In the Gantt chart, the zoom-in and zoom-out actions are performed based on the predefined zooming Levels. You can customize the zooming actions by defining the required zooming levels to the [CustomZoomingLevels](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_CustomZoomingLevels) property. +Zoom actions are governed by predefined zooming levels specified in the [CustomZoomingLevels](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_CustomZoomingLevels) property. These levels can be customized by assigning a collection of zoom configurations to the `CustomZoomingLevels` property. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -105,47 +109,127 @@ In the Gantt chart, the zoom-in and zoom-out actions are performed based on the public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } + public string TaskName { get; set; } + public DateTime StartDate { get; set; } + public DateTime EndDate { get; set; } + public string Duration { get; set; } + public int Progress { get; set; } + public string Predecessor { get; set; } + public int? ParentID { get; set; } + } + + public static List GetTaskCollection() + { + List Tasks = new List() + { + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 11), EndDate = new DateTime(2022, 04, 18), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentID = 5 }, + }; + return Tasks; + } +} + +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/VtBysjWwqJeIdgws?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} + +## Zoom actions via methods + +Zooming actions can be triggered dynamically or through external controls using the following methods: + +* **Zoom In** - Use `ZoomIn` when `ZoomIn` external button was clicked, the timeline cell width is increased when the cell size exceeds the specified range and the timeline unit is changed based on the current zoom levels. +* **Zoom Out** - Use `ZoomOut` when the `ZoomOut` external button was clicked, the timeline cell width is decreased when the cell size falls behind the specified range and the timeline view mode is changed based on the current zooming levels. +* **Zoom To Fit** - Use `ZoomToFitAsync` When `Fit To Project` external button was clicked then all the tasks are rendered within the available chart container width. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} + +@using Syncfusion.Blazor.Gantt + + + + + + + + + + + +@code { + private SfGantt Gantt; + private List TaskCollection { get; set; } + protected override void OnInitialized() + { + this.TaskCollection = GetTaskCollection(); + } + private async void ZoomIn() + { + await Gantt.ZoomInAsync(); + } + private async void ZoomOut() + { + await Gantt.ZoomOutAsync(); + } + private async void ZoomToFit() + { + await Gantt.ZoomToFitAsync(); + } + public class TaskData + { + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } public string Predecessor { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentId = 5 }, + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentID = 5 }, }; return Tasks; } } -``` -![Customizing zooming levels in Blazor Gantt Chart](images/blazor-gantt-chart-custom-zooming-levels.gif) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/hjryCNMwUIBQDMde?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} ## Resetting zooming levels using method -In Gantt chart, you can reset the zoom level to its initial state, as configured during the initial rendering, after performing zooming actions like ZoomIn, ZoomOut, and ZoomToFit, using [ResetZoomAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ResetZoomAsync) method. +In Gantt chart, you can reset the zoom level to its initial state, as configured during the initial rendering, after performing zooming actions like **ZoomIn**, **ZoomOut**, and **ZoomToFit**, using [ResetZoomAsync](https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Gantt.SfGantt-1.html#Syncfusion_Blazor_Gantt_SfGantt_1_ResetZoomAsync) method. + +{% tabs %} +{% highlight razor tabtitle="Index.razor" %} -```cshtml @using Syncfusion.Blazor.Gantt - + @@ -163,32 +247,34 @@ In Gantt chart, you can reset the zoom level to its initial state, as configured } public class TaskData { - public int TaskId { get; set; } + public int TaskID { get; set; } public string TaskName { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string Duration { get; set; } public int Progress { get; set; } public string Predecessor { get; set; } - public int? ParentId { get; set; } + public int? ParentID { get; set; } } public static List GetTaskCollection() { List Tasks = new List() { - new TaskData() { TaskId = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentId = 1 }, - new TaskData() { TaskId = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentId = 1 }, - new TaskData() { TaskId = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentId = 1 }, - new TaskData() { TaskId = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 06), EndDate = new DateTime(2022, 04, 21), }, - new TaskData() { TaskId = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentId = 5 }, - new TaskData() { TaskId = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentId = 5 }, - new TaskData() { TaskId = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentId = 5 }, + new TaskData() { TaskID = 1, TaskName = "Project initiation", StartDate = new DateTime(2022, 04, 05), EndDate = new DateTime(2022, 04, 08), }, + new TaskData() { TaskID = 2, TaskName = "Identify Site location", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, ParentID = 1 }, + new TaskData() { TaskID = 3, TaskName = "Perform soil test", StartDate = new DateTime(2022, 04, 05), Duration = "4", Progress = 40, Predecessor = "2", ParentID = 1 }, + new TaskData() { TaskID = 4, TaskName = "Soil test approval", StartDate = new DateTime(2022, 04, 05), Duration = "0", Progress = 30, Predecessor = "3", ParentID = 1 }, + new TaskData() { TaskID = 5, TaskName = "Project estimation", StartDate = new DateTime(2022, 04, 11), EndDate = new DateTime(2022, 04, 18), }, + new TaskData() { TaskID = 6, TaskName = "Develop floor plan for estimation", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 30, Predecessor = "4", ParentID = 5 }, + new TaskData() { TaskID = 7, TaskName = "List materials", StartDate = new DateTime(2022, 04, 06), Duration = "3", Progress = 40, Predecessor = "6", ParentID = 5 }, + new TaskData() { TaskID = 8, TaskName = "Estimation approval", StartDate = new DateTime(2022, 04, 06), Duration = "0", Progress = 30, Predecessor = "7", ParentID = 5 }, }; return Tasks; } } -``` -![Resetting zooming levels in Blazor Gantt Chart](images/blazor-gantt-chart-zooming-reset.gif) +{% endhighlight %} +{% endtabs %} + +{% previewsample "https://blazorplayground.syncfusion.com/embed/hNreMNCGgopuohOR?appbar=false&editor=false&result=true&errorlist=false&theme=bootstrap5" %} \ No newline at end of file From abcd39a74b67696b74f51b19c084890446d3670b Mon Sep 17 00:00:00 2001 From: NithyaSivaprakasam <103498896+NithyaSivaprakasam@users.noreply.github.com> Date: Tue, 4 Nov 2025 19:28:01 +0530 Subject: [PATCH 2/2] Update title for Gantt Chart PDF customization --- blazor/gantt-chart/header-and-footer.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/blazor/gantt-chart/header-and-footer.md b/blazor/gantt-chart/header-and-footer.md index b03b2c2ae6..597cda6faf 100644 --- a/blazor/gantt-chart/header-and-footer.md +++ b/blazor/gantt-chart/header-and-footer.md @@ -1,6 +1,6 @@ --- layout: post -title: Customizing PDF Headers and Footers in Blazor Gantt Chart Component | Syncfusion +title: Customizing PDF Headers and Footers in Syncfusion Blazor Gantt Chart description: Learn how to customize headers and footers in PDF exports of the Syncfusion Blazor Gantt Chart component with text, lines, page numbers, and images. platform: Blazor control: header and footer of PDF exporting @@ -203,4 +203,4 @@ Supported line styles are, ## See also - [How to export to PDF?](https://blazor.syncfusion.com/documentation/gantt-chart/pdf-export) -- [How to manage task dependencies?](https://blazor.syncfusion.com/documentation/gantt-chart/task-dependencies) \ No newline at end of file +- [How to manage task dependencies?](https://blazor.syncfusion.com/documentation/gantt-chart/task-dependencies)