diff --git a/KB-Samples/DiagramWithListBox/DiagramWithListBox_NET6.csproj b/KB-Samples/DiagramWithListBox/DiagramWithListBox_NET10.csproj
similarity index 78%
rename from KB-Samples/DiagramWithListBox/DiagramWithListBox_NET6.csproj
rename to KB-Samples/DiagramWithListBox/DiagramWithListBox_NET10.csproj
index 5b747ab8..8438d972 100644
--- a/KB-Samples/DiagramWithListBox/DiagramWithListBox_NET6.csproj
+++ b/KB-Samples/DiagramWithListBox/DiagramWithListBox_NET10.csproj
@@ -1,12 +1,13 @@
- net6.0
+ net10.0
enable
enable
+
diff --git a/KB-Samples/DiagramWithListBox/DiagramWithListBox_NET8.csproj b/KB-Samples/DiagramWithListBox/DiagramWithListBox_NET8.csproj
index 3c5230c5..71217009 100644
--- a/KB-Samples/DiagramWithListBox/DiagramWithListBox_NET8.csproj
+++ b/KB-Samples/DiagramWithListBox/DiagramWithListBox_NET8.csproj
@@ -6,7 +6,8 @@
enable
-
+
+
\ No newline at end of file
diff --git a/KB-Samples/DiagramWithListBox/Pages/Index.razor b/KB-Samples/DiagramWithListBox/Pages/Index.razor
index f7c1f349..64f56e89 100644
--- a/KB-Samples/DiagramWithListBox/Pages/Index.razor
+++ b/KB-Samples/DiagramWithListBox/Pages/Index.razor
@@ -1,9 +1,10 @@
@page "/"
+
@using Syncfusion.Blazor.DropDowns
@using Syncfusion.Blazor.Diagram
@using System.Text.Json
-@using Microsoft.JSInterop;
-@inject IJSRuntime jsRuntime;
+@using Microsoft.JSInterop;
+@inject IJSRuntime JsRuntime;
@using Microsoft.AspNetCore.Components;
@@ -17,10 +18,10 @@
@@ -29,7 +30,7 @@
@@ -38,15 +39,41 @@
@code {
- public SfDiagramComponent Diagram;
- SfListBox ListBoxObj;
+ private SfDiagramComponent diagram;
+ private SfListBox listBoxObj;
private List filteredData = new List();
private string sampleData = "[{\"Extractor\":\"Facebook Ads\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"FileSystem\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"GitHub\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Google Analytics\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Google Sheets\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"HubSpot\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Jira\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Matomo\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"MongoDB\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"MSSQL\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Mux\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"MySQL\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Notion\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"OpenAPI\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Oracle\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Pipedrive\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"PostgreSQL\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Salesforce\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Slack\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Strapi\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Stripe\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Web\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"Workable\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"ZendeskChat\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"ZendeskSupport\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"},{\"Extractor\":\"ZendeskTalk\",\"yamlfile\":\"version: 1\\r\\nencrypt_credentials: false\\r\\nplugins:\\r\\n extractors:\"}]";
+ //Define diagram's swimlane collection.
+ private DiagramObjectCollection swimlaneCollections = new DiagramObjectCollection();
+
protected override async Task OnInitializedAsync()
{
// Deserialize sample data into ListBox items
filteredData = System.Text.Json.JsonSerializer.Deserialize>(sampleData);
+
+ Swimlane swimlane1 = new Swimlane()
+ {
+ ID = "Swimlane1",
+ OffsetX = 400,
+ OffsetY = 200,
+ Height = 500,
+ Width = 300,
+ Orientation = Orientation.Horizontal,
+ };
+ // Add swimlane.
+ swimlaneCollections.Add(swimlane1);
+ Swimlane swimlane2 = new Swimlane()
+ {
+ ID = "Swimlane2",
+ OffsetX = 800,
+ OffsetY = 200,
+ Height = 500,
+ Width = 300,
+ Orientation = Orientation.Vertical,
+ };
+ // Add swimlane.
+ swimlaneCollections.Add(swimlane2);
}
private readonly string scope = "combined-list";
@@ -70,49 +97,161 @@
public class ExtractorUI
{
public string Extractor { get; set; }
- public string yamlfile { get; set; }
+ public string YamlFile { get; set; }
public bool IsEdited { get; set; }
public bool IsCustom { get; set; }
}
}
@code {
- DiagramPoint currentPosition;
- bool isDragging;
+ private DiagramPoint currentPosition;
+ private bool isDragging;
// Sets dragging state when drag begins
- public void DragSrart(DragEventArgs args)
+ public void DragStart(DragEventArgs args)
{
isDragging = true;
}
- // Handles drop event to add ListBox items as nodes in the Diagram
+
public async void OnDrop(DropEventArgs args)
{
- ExtractorUI item = args.Items.First();
- if (isDragging)
+ if (!isDragging)
+ {
+ currentPosition = null;
+ return;
+ }
+
+ // Compute drop position
+ (double dropX, double dropY) = await GetDropPositionAsync(args);
+
+ // Build node
+ Node droppedNode = CreateDroppedNode(args, dropX, dropY);
+
+ // Try placing inside swimlanes
+ if (diagram?.Swimlanes != null && diagram.Swimlanes.Count > 0 &&
+ TryPlaceInSwimlanes(droppedNode, dropX, dropY))
{
- // Fetch ListBox width to adjust positioning
- string listViewWith = await jsRuntime.InvokeAsync("getlistViewWidth", "listbox");
- double listViewWithDoubleValue = Double.Parse(listViewWith);
- // Add a new node to Diagram based on ListBox item details
- await Diagram.AddDiagramElementsAsync(new DiagramObjectCollection()
- {
- new Node()
- {
- Height = 100,
- Width = 100,
- OffsetX = args.Left-listViewWithDoubleValue,
- OffsetY = args.Top,
- Annotations = new DiagramObjectCollection()
- {
- new ShapeAnnotation()
- {
- Content = (args.Items.FirstOrDefault() as ExtractorUI)?.Extractor,
- }
- }
- }
- });
isDragging = false;
+ currentPosition = null;
+ return;
}
+
+ // Fallback: add to root
+ await diagram.AddDiagramElementsAsync(new DiagramObjectCollection { droppedNode });
+ isDragging = false;
currentPosition = null;
}
+
+ private async Task<(double x, double y)> GetDropPositionAsync(DropEventArgs args)
+ {
+ string listWidthStr = await JsRuntime.InvokeAsync("getlistViewWidth", "listbox");
+ double listWidth = Double.Parse(listWidthStr);
+ return (args.Left - listWidth, args.Top);
+ }
+
+ private static Node CreateDroppedNode(DropEventArgs args, double x, double y)
+ {
+ return new Node
+ {
+ Height = 100,
+ Width = 100,
+ OffsetX = x,
+ OffsetY = y,
+ Annotations = new DiagramObjectCollection
+ {
+ new ShapeAnnotation { Content = (args.Items.FirstOrDefault() as ExtractorUI)?.Extractor }
+ }
+ };
+ }
+
+ private bool TryPlaceInSwimlanes(Node droppedNode, double x, double y)
+ {
+ foreach (Swimlane swimlane in diagram.Swimlanes)
+ {
+ if (swimlane?.Lanes == null || swimlane.Lanes.Count == 0)
+ continue;
+
+ if (swimlane.Orientation == Orientation.Horizontal)
+ {
+ if (TryPlaceInHorizontalLanes(swimlane, droppedNode, x, y))
+ return true;
+ }
+ else
+ {
+ if (TryPlaceInVerticalLanes(swimlane, droppedNode, x, y))
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private static bool TryPlaceInHorizontalLanes(Swimlane swimlane, Node droppedNode, double x, double y)
+ {
+ double swWidth = swimlane.Width ?? 0d;
+ double swHeight = swimlane.Height ?? 0d;
+ double left = swimlane.OffsetX - swWidth / 2d;
+ double top = swimlane.OffsetY - swHeight / 2d;
+
+ double headerWidth = swimlane.Header?.Width ?? 0d;
+
+ double contentLeft = left + headerWidth;
+ double contentTop = top;
+ double contentWidth = Math.Max(0d, swWidth - headerWidth);
+
+ double laneTop = contentTop;
+
+ foreach (Lane lane in swimlane.Lanes)
+ {
+ double laneHeight = lane.Height ?? 0d;
+ if (laneHeight <= 0d) { continue; }
+
+ if (PointInRect(x, y, contentLeft, laneTop, contentWidth, laneHeight))
+ {
+ lane.Children.Add(droppedNode);
+ return true;
+ }
+
+ laneTop += laneHeight;
+ }
+
+ return false;
+ }
+
+ private static bool TryPlaceInVerticalLanes(Swimlane swimlane, Node droppedNode, double x, double y)
+ {
+ double swWidth = swimlane.Width ?? 0d;
+ double swHeight = swimlane.Height ?? 0d;
+ double left = swimlane.OffsetX - swWidth / 2d;
+ double top = swimlane.OffsetY - swHeight / 2d;
+
+ double headerHeight = swimlane.Header?.Height ?? 0d;
+
+ double contentLeft = left;
+ double contentTop = top + headerHeight;
+ double contentHeight = Math.Max(0d, swHeight - headerHeight);
+
+ double laneLeft = contentLeft;
+
+ foreach (Lane lane in swimlane.Lanes)
+ {
+ double laneWidth = lane.Width ?? 0d;
+ if (laneWidth <= 0d) { continue; }
+
+ if (PointInRect(x, y, laneLeft, contentTop, laneWidth, contentHeight))
+ {
+ lane.Children.Add(droppedNode);
+ return true;
+ }
+
+ laneLeft += laneWidth;
+ }
+
+ return false;
+ }
+
+ private static bool PointInRect(double x, double y, double left, double top, double width, double height)
+ {
+ return x >= left && x <= left + width && y >= top && y <= top + height;
+ }
+
+ }
}
diff --git a/KB-Samples/DiagramWithListBox/Pages/_Layout.cshtml b/KB-Samples/DiagramWithListBox/Pages/_Layout.cshtml
index 637d24d9..089cf6bc 100644
--- a/KB-Samples/DiagramWithListBox/Pages/_Layout.cshtml
+++ b/KB-Samples/DiagramWithListBox/Pages/_Layout.cshtml
@@ -10,7 +10,6 @@
-
@@ -18,7 +17,9 @@
@RenderBody()
-
+
+
+