diff --git a/KB-Samples/LargeDiagram/Components/App.razor b/KB-Samples/LargeDiagram/Components/App.razor
new file mode 100644
index 00000000..f89f0045
--- /dev/null
+++ b/KB-Samples/LargeDiagram/Components/App.razor
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/KB-Samples/LargeDiagram/Components/Layout/MainLayout.razor b/KB-Samples/LargeDiagram/Components/Layout/MainLayout.razor
new file mode 100644
index 00000000..f170e386
--- /dev/null
+++ b/KB-Samples/LargeDiagram/Components/Layout/MainLayout.razor
@@ -0,0 +1,9 @@
+@inherits LayoutComponentBase
+
+
diff --git a/KB-Samples/LargeDiagram/Components/Layout/MainLayout.razor.css b/KB-Samples/LargeDiagram/Components/Layout/MainLayout.razor.css
new file mode 100644
index 00000000..08472038
--- /dev/null
+++ b/KB-Samples/LargeDiagram/Components/Layout/MainLayout.razor.css
@@ -0,0 +1,98 @@
+.page {
+ position: relative;
+ display: flex;
+ flex-direction: column;
+}
+
+main {
+ flex: 1;
+}
+
+.sidebar {
+ background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%);
+}
+
+.top-row {
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #d6d5d5;
+ justify-content: flex-end;
+ height: 3.5rem;
+ display: flex;
+ align-items: center;
+}
+
+.top-row ::deep a, .top-row ::deep .btn-link {
+ white-space: nowrap;
+ margin-left: 1.5rem;
+ text-decoration: none;
+}
+
+.top-row ::deep a:hover, .top-row ::deep .btn-link:hover {
+ text-decoration: underline;
+}
+
+.top-row ::deep a:first-child {
+ overflow: hidden;
+ text-overflow: ellipsis;
+}
+
+@media (max-width: 640.98px) {
+ .top-row {
+ justify-content: space-between;
+ }
+
+ .top-row ::deep a, .top-row ::deep .btn-link {
+ margin-left: 0;
+ }
+}
+
+@media (min-width: 641px) {
+ .page {
+ flex-direction: row;
+ }
+
+ .sidebar {
+ width: 250px;
+ height: 100vh;
+ position: sticky;
+ top: 0;
+ }
+
+ .top-row {
+ position: sticky;
+ top: 0;
+ z-index: 1;
+ }
+
+ .top-row.auth ::deep a:first-child {
+ flex: 1;
+ text-align: right;
+ width: 0;
+ }
+
+ .top-row, article {
+ padding-left: 2rem !important;
+ padding-right: 1.5rem !important;
+ }
+}
+
+#blazor-error-ui {
+ color-scheme: light only;
+ background: lightyellow;
+ bottom: 0;
+ box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2);
+ box-sizing: border-box;
+ display: none;
+ left: 0;
+ padding: 0.6rem 1.25rem 0.7rem 1.25rem;
+ position: fixed;
+ width: 100%;
+ z-index: 1000;
+}
+
+#blazor-error-ui .dismiss {
+ cursor: pointer;
+ position: absolute;
+ right: 0.75rem;
+ top: 0.5rem;
+}
diff --git a/KB-Samples/LargeDiagram/Components/Pages/DiagramFeatures.razor b/KB-Samples/LargeDiagram/Components/Pages/DiagramFeatures.razor
new file mode 100644
index 00000000..7c0d3b0f
--- /dev/null
+++ b/KB-Samples/LargeDiagram/Components/Pages/DiagramFeatures.razor
@@ -0,0 +1,350 @@
+@page "/"
+
+@using Syncfusion.Blazor.Diagram
+@using Syncfusion.Blazor.Diagram.SymbolPalette
+@using Syncfusion.Blazor.Buttons
+@using Microsoft.JSInterop
+@using Syncfusion.Blazor.Navigations
+@using Syncfusion.Blazor.Inputs
+@rendermode InteractiveServer
+@using LargeDiagram.Components.Pages
+@inject IJSRuntime jsRuntime
+
+
+
+
+
+
+
+
+
+
+
+
+
+ DiagramComponent
+
+
+
+
+ Save
+ Load
+
+
+
+
+
+
+
+
+
+
+
+@code {
+ //Reference to uploder
+ SfUploader uploadFiles;
+ SfDiagramComponent diagram;
+ private string fileName;
+ // Method to customize the tool
+ public InteractionControllerBase GetCustomTool(DiagramElementAction action, string id)
+ {
+ InteractionControllerBase tool = null;
+ if (id == "Draw")
+ {
+ tool = new DrawTool(diagram);
+ }
+ else
+ {
+ tool = new AddDeleteTool(diagram);
+ }
+ return tool;
+ }
+ // Custom tool to delete the node.
+ public class AddDeleteTool : InteractionControllerBase
+ {
+ SfDiagramComponent sfDiagram;
+ Node deleteObject = null;
+ public AddDeleteTool(SfDiagramComponent Diagram) : base(Diagram)
+ {
+ sfDiagram = Diagram;
+ }
+ public override void OnMouseDown(DiagramMouseEventArgs args)
+ {
+ if (sfDiagram.SelectionSettings.Nodes.Count > 0 && ((sfDiagram.SelectionSettings.Nodes[0]) is Node))
+ {
+ deleteObject = (sfDiagram.SelectionSettings.Nodes[0]) as Node;
+ }
+ base.OnMouseDown(args);
+ }
+ public override void OnMouseUp(DiagramMouseEventArgs args)
+ {
+ if (deleteObject != null)
+ {
+ sfDiagram.StartGroupAction();
+ sfDiagram.BeginUpdate();
+ sfDiagram.Nodes.Remove(deleteObject);
+ _ = sfDiagram.EndUpdateAsync();
+ sfDiagram.EndGroupAction();
+ }
+ base.OnMouseUp(args);
+ this.InAction = true;
+ }
+ }
+ public class DrawTool : ConnectorDrawingController
+ {
+ SfDiagramComponent sfDiagram;
+ Connector newConnector = null;
+ public DrawTool(SfDiagramComponent Diagram) : base(Diagram, DiagramElementAction.ConnectorSourceEnd)
+ {
+ sfDiagram = Diagram;
+ newConnector = new Connector()
+ {
+ ID = "OrthogonalConnector",
+ SourceID = sfDiagram.SelectionSettings.Nodes[0].ID,
+ Type = ConnectorSegmentType.Orthogonal,
+ };
+ Diagram.InteractionController = DiagramInteractions.DrawOnce;
+ Diagram.DrawingObject = newConnector;
+ }
+ public override void OnMouseDown(DiagramMouseEventArgs args)
+ {
+ base.OnMouseDown(args);
+ }
+ public override void OnMouseUp(DiagramMouseEventArgs args)
+ {
+ base.OnMouseUp(args);
+ }
+ }
+ DiagramObjectCollection Nodes = new DiagramObjectCollection();
+ DiagramObjectCollection Connectors = new DiagramObjectCollection();
+ private string ExtensionType = ".json";
+ //Method to save the diagram
+ public async Task SaveDiagram()
+ {
+ fileName = await jsRuntime.InvokeAsync("getDiagramFileName", "");
+ await DownloadDiagram(fileName);
+ }
+
+ //Method to download the diagram
+ public async Task DownloadDiagram(string fileName)
+ {
+ string data = diagram.SaveDiagram();
+ await FileUtil.SaveAs(jsRuntime, data, fileName);
+ }
+
+ //Method to load the diagram
+ public async Task LoadDiagram()
+ {
+ diagram.BeginUpdate();
+ ExtensionType = ".json";
+ await FileUtil.Click(jsRuntime);
+ await diagram.EndUpdateAsync();
+ }
+ string json;
+ public async Task OnUploadFileSelected(UploadingEventArgs args)
+ {
+ if (args.FileData.Type == "json")
+ {
+ json = await FileUtil.LoadFile(jsRuntime, args.FileData);
+ json = json.Replace(System.Environment.NewLine, string.Empty);
+ await diagram.LoadDiagramAsync(json.ToString());
+ await uploadFiles.ClearAllAsync();
+ }
+ }
+ protected override async Task OnAfterRenderAsync(bool firstRender)
+ {
+ SymbolPalette.Targets = new DiagramObjectCollection() { };
+ SymbolPalette.Targets.Add(diagram);
+ }
+
+ private async void OnCreate()
+ {
+ json = File.ReadAllText("wwwroot/PathShape.json");
+ await diagram.LoadDiagramAsync(json);
+ }
+ SymbolMargin SymbolMargin = new SymbolMargin
+ {
+ Left = 15,
+ Right = 15,
+ Top = 15,
+ Bottom = 15
+ };
+ SfSymbolPaletteComponent SymbolPalette;
+ DiagramObjectCollection Palettes = new DiagramObjectCollection();
+ DiagramObjectCollection PaletteNodes = new DiagramObjectCollection();
+ DiagramObjectCollection PalettePathNodes = new DiagramObjectCollection();
+
+ protected override void OnInitialized()
+ {
+ InitPaletteModel();
+ }
+
+ private void InitPaletteModel()
+ {
+ CreatePalettPathNode("Decision");
+ CreatePalettPathNode("Process");
+ CreatePalettPathNode("Terminator");
+ CreatePalettPathNode("Event");
+ CreatePalettPathNode("Delay");
+ CreatePalettPathNode("Manual-Operation");
+ CreatePalettPathNode("Manual-Input");
+ CreatePalettPathNode("Data");
+ CreatePalettPathNode("Card");
+ CreatePaletteNode(NodeBasicShapes.Rectangle, "Rectangle");
+ CreatePaletteNode(NodeBasicShapes.Ellipse, "Ellipse");
+ CreatePaletteNode(NodeBasicShapes.Diamond, "Diamond");
+ CreatePaletteNode(NodeBasicShapes.Rectangle, "Rectangle");
+ CreatePaletteNode(NodeBasicShapes.Ellipse, "Ellipse");
+ CreatePaletteNode(NodeBasicShapes.Star, "Star");
+ Palettes = new DiagramObjectCollection()
+ {
+ new Palette(){Symbols = PaletteNodes,Title = "Basic Shapes", ID = "Basic Shapes" },
+ new Palette(){Symbols = PalettePathNodes,Title = "Path Shapes", ID = "Path Shapes" },
+ };
+ }
+ private void CreatePaletteNode(NodeBasicShapes basicShape, string id)
+ {
+ Node node = new Node()
+ {
+ ID = id,
+ Shape = new BasicShape() { Type = NodeShapes.Basic, Shape = basicShape },
+ Style = new ShapeStyle() { Fill = "#6495ED", StrokeColor = "#6495ED" },
+ };
+ PaletteNodes.Add(node);
+ }
+ private void CreatePalettPathNode(string id, bool isShadow = false)
+ {
+ Node diagramNode = new Node()
+ {
+ ID = id,
+ Style = new ShapeStyle()
+ {
+ StrokeColor = "#2847e5",
+ StrokeWidth = 1,
+ Gradient = new LinearGradientBrush()
+ {
+ X1 = 0,
+ Y1 = 0,
+ X2 = 50,
+ Y2 = 50,
+ GradientStops = new DiagramObjectCollection()
+ {
+ new GradientStop(){ Color = "Black", Offset = 0},
+ new GradientStop(){ Color = "#4b1a4d", Offset = 100}
+ },
+ }
+ },
+ Annotations = new DiagramObjectCollection()
+ {
+ new ShapeAnnotation()
+ {
+ Style = new TextStyle()
+ {
+ Color = "White",
+ FontSize = 16,
+ Bold = false,
+ TextOverflow = TextOverflow.Wrap,
+ TextWrapping = Syncfusion.Blazor.Diagram.TextWrap.WrapWithOverflow
+ }
+ }
+ }
+ };
+
+ if (id == "Decision")
+ {
+ diagramNode.Shape = new PathShape() { Type = Syncfusion.Blazor.Diagram.NodeShapes.Path, Data = "M 5 45 L 45, 5 Q 50 0 55 5 L 95 45 Q 100 50 95 55 L 55 95 Q 50 100 45 95 L 5 55 Q 0 50 5 45 Z" };
+ diagramNode.Width = 100;
+ diagramNode.Height = 100;
+ diagramNode.Style.Fill = "#114e0f";
+ diagramNode.Style.Gradient!.GradientStops[0].Color = "Black";
+ diagramNode.Style.Gradient.GradientStops[1].Color = "#114e0f";
+ }
+ else if (id == "Process")
+ {
+ diagramNode.Shape = new PathShape() { Type = Syncfusion.Blazor.Diagram.NodeShapes.Path, Data = "M 5 0 L135 0 Q 140 0 140 5 L 140 65 Q 140 70 135 70 L 5 70 Q 0 70 0 65 L 0 5 Q 0 0 5 0 Z" };
+ diagramNode.Width = 140;
+ diagramNode.Height = 70;
+ diagramNode.Style.Fill = "#173987";
+ diagramNode.Style.Gradient!.GradientStops[0].Color = "Black";
+ diagramNode.Style.Gradient.GradientStops[1].Color = "#173987";
+ }
+ else if (id == "Terminator")
+ {
+ diagramNode.Shape = new PathShape() { Type = Syncfusion.Blazor.Diagram.NodeShapes.Path, Data = "M 20 0 L 120 0 Q 140 0 140 20 Q 140 40 120 40 L 20 40 Q 0 40 0 20 Q 0 0 20 0 Z" };
+ diagramNode.Width = 140;
+ diagramNode.Height = 40;
+ diagramNode.Style.Fill = "#405176";
+ diagramNode.Style.Gradient!.GradientStops[0].Color = "Black";
+ diagramNode.Style.Gradient.GradientStops[1].Color = "#405176";
+ }
+ else if (id == "Event")
+ {
+ diagramNode.Shape = new PathShape() { Type = Syncfusion.Blazor.Diagram.NodeShapes.Path, Data = "M 20 0 L 120 0 Q 140 0 140 20 L 140 50 Q 140 70 120 70 L 20 70 Q 0 70 0 50 L 0 20 Q 0 0 20 0 Z" };
+ diagramNode.Width = 140;
+ diagramNode.Height = 70;
+ diagramNode.Style.Fill = "#173987";
+ diagramNode.Style.Gradient!.GradientStops[0].Color = "Black";
+ diagramNode.Style.Gradient.GradientStops[1].Color = "#173987";
+ }
+ else if (id == "Delay")
+ {
+ diagramNode.Shape = new PathShape() { Type = Syncfusion.Blazor.Diagram.NodeShapes.Path, Data = "M 0 0 L 105 0 Q 140 0 140 35 Q 140 70 105 70 L 0 70 L 0 0 Z" };
+ diagramNode.Width = 140;
+ diagramNode.Height = 70;
+ diagramNode.Style.Fill = "#493e13";
+ diagramNode.Style.Gradient!.GradientStops[0].Color = "Black";
+ diagramNode.Style.Gradient.GradientStops[1].Color = "#493e13";
+ }
+ else if (id == "Manual-Operation")
+ {
+ diagramNode.Shape = new PathShape() { Type = Syncfusion.Blazor.Diagram.NodeShapes.Path, Data = "M 0 0 L 140 0 L 115 70 L 25 70 L 0 0 Z" };
+ diagramNode.Width = 140;
+ diagramNode.Height = 70;
+ diagramNode.Style.Fill = "#310031";
+ diagramNode.Style.Gradient!.GradientStops[0].Color = "Black";
+ diagramNode.Style.Gradient.GradientStops[1].Color = "#310031";
+ }
+ else if (id == "Manual-Input")
+ {
+ diagramNode.Shape = new PathShape() { Type = Syncfusion.Blazor.Diagram.NodeShapes.Path, Data = "M 140 0 L 140 60 Q 140 70 120 70 L 10 70 Q 0 70 0 60 L 0 35 L 140 0 Z" };
+ diagramNode.Width = 140;
+ diagramNode.Height = 70;
+ diagramNode.Style.Fill = "#4b1a4d";
+ diagramNode.Style.Gradient!.GradientStops[0].Color = "Black";
+ diagramNode.Style.Gradient.GradientStops[1].Color = "#4b1a4d";
+ }
+ else if (id == "Data")
+ {
+ diagramNode.Shape = new PathShape() { Type = Syncfusion.Blazor.Diagram.NodeShapes.Path, Data = "M 20 0 L 140 0 L 120 70 L 0 70 L 2 0 Z" };
+ diagramNode.Width = 140;
+ diagramNode.Height = 70;
+ diagramNode.Style.Fill = "#5a1414";
+ diagramNode.Style.Gradient!.GradientStops[0].Color = "Black";
+ diagramNode.Style.Gradient.GradientStops[1].Color = "#5a1414";
+ }
+ else if (id == "Card")
+ {
+ diagramNode.Shape = new PathShape() { Type = Syncfusion.Blazor.Diagram.NodeShapes.Path, Data = "M 35 0 L 130 0 Q 140 0 140 10 L 140 60 Q 140 70 130 70 L 10 70 Q 0 70 0 60 L 0 35 L 35 0 Z" };
+ diagramNode.Width = 140;
+ diagramNode.Height = 70;
+ diagramNode.Style.Fill = "#68682f";
+ diagramNode.Style.Gradient!.GradientStops[0].Color = "Black";
+ diagramNode.Style.Gradient.GradientStops[1].Color = "#68682f";
+ }
+
+ // Add shadow effect if requested
+ if (isShadow)
+ {
+ diagramNode.Shadow = new Shadow()
+ {
+ Angle = 45,
+ Color = "lightgrey",
+ Distance = 5,
+ Opacity = 0.7
+ };
+ }
+ PalettePathNodes.Add(diagramNode);
+ }
+}
+
diff --git a/KB-Samples/LargeDiagram/Components/Pages/FileUtil.cs b/KB-Samples/LargeDiagram/Components/Pages/FileUtil.cs
new file mode 100644
index 00000000..23f4614d
--- /dev/null
+++ b/KB-Samples/LargeDiagram/Components/Pages/FileUtil.cs
@@ -0,0 +1,25 @@
+using Microsoft.JSInterop;
+
+namespace LargeDiagram.Components.Pages
+{
+
+ public class FileUtil
+ {
+ public async static Task SaveAs(IJSRuntime js, string data, string fileName)
+ {
+ await js.InvokeAsync