Skip to content

Commit ccd1dc2

Browse files
committed
feat: Add algorithms project with links reconnection algorithm
1 parent d39d77d commit ccd1dc2

File tree

9 files changed

+179
-1
lines changed

9 files changed

+179
-1
lines changed

Blazor.Diagrams.sln

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharedDemo", "samples\Share
1717
EndProject
1818
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ServerSide", "samples\ServerSide\ServerSide.csproj", "{B9EE910B-8FE7-490C-B20C-CEC27A2890D6}"
1919
EndProject
20+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Blazor.Diagrams.Algorithms", "src\Blazor.Diagrams.Algorithms\Blazor.Diagrams.Algorithms.csproj", "{CB3A42B6-3C87-4ECB-B60C-D98275AB1FB6}"
21+
EndProject
2022
Global
2123
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2224
Debug|Any CPU = Debug|Any CPU
@@ -43,6 +45,10 @@ Global
4345
{B9EE910B-8FE7-490C-B20C-CEC27A2890D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
4446
{B9EE910B-8FE7-490C-B20C-CEC27A2890D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
4547
{B9EE910B-8FE7-490C-B20C-CEC27A2890D6}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{CB3A42B6-3C87-4ECB-B60C-D98275AB1FB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49+
{CB3A42B6-3C87-4ECB-B60C-D98275AB1FB6}.Debug|Any CPU.Build.0 = Debug|Any CPU
50+
{CB3A42B6-3C87-4ECB-B60C-D98275AB1FB6}.Release|Any CPU.ActiveCfg = Release|Any CPU
51+
{CB3A42B6-3C87-4ECB-B60C-D98275AB1FB6}.Release|Any CPU.Build.0 = Release|Any CPU
4652
EndGlobalSection
4753
GlobalSection(SolutionProperties) = preSolution
4854
HideSolutionNode = FALSE
@@ -53,6 +59,7 @@ Global
5359
{A1A4F8A5-7C97-41A8-9ADD-54E9D1725B56} = {EE32E278-A887-454E-987D-FFE9E37169FE}
5460
{1CBCC8E6-111C-4364-9882-50881E4CC8B4} = {DA819127-3EF6-4EB9-A2DA-BC056B284A50}
5561
{B9EE910B-8FE7-490C-B20C-CEC27A2890D6} = {DA819127-3EF6-4EB9-A2DA-BC056B284A50}
62+
{CB3A42B6-3C87-4ECB-B60C-D98275AB1FB6} = {EE32E278-A887-454E-987D-FFE9E37169FE}
5663
EndGlobalSection
5764
GlobalSection(ExtensibilityGlobals) = postSolution
5865
SolutionGuid = {969540A2-8162-4063-A4E3-B488F69BD582}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
@page "/demos/reconnect-links"
2+
@inherits ReconnectLinksToClosestPortsComponent
3+
@layout DemoLayout
4+
@inject LayoutData LayoutData
5+
6+
@code {
7+
protected override void OnInitialized()
8+
{
9+
base.OnInitialized();
10+
11+
LayoutData.Title = "Reconnect links";
12+
LayoutData.Info = "An example of reconnecting links to the closest ports.";
13+
LayoutData.DataChanged();
14+
}
15+
}
16+
17+
<div style="position: absolute; z-index: 9999;">
18+
<button @onclick="ReconnectLinks">Reconnect links</button>
19+
</div>
20+
21+
<CascadingValue Name="DiagramManager" Value="diagramManager">
22+
<DiagramCanvas>
23+
<Widgets>
24+
<Navigator Width="300" Height="200" DefaultStyle="true"></Navigator>
25+
</Widgets>
26+
</DiagramCanvas>
27+
</CascadingValue>
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
using Blazor.Diagrams.Algorithms;
2+
using Blazor.Diagrams.Core;
3+
using Blazor.Diagrams.Core.Models;
4+
using Blazor.Diagrams.Core.Models.Core;
5+
using Microsoft.AspNetCore.Components;
6+
7+
namespace SharedDemo.Demos.Algorithms
8+
{
9+
public class ReconnectLinksToClosestPortsComponent : ComponentBase
10+
{
11+
protected readonly DiagramManager diagramManager = new DiagramManager();
12+
13+
protected override void OnInitialized()
14+
{
15+
base.OnInitialized();
16+
17+
var node1 = NewNode(50, 50);
18+
var node2 = NewNode(300, 300);
19+
var node3 = NewNode(300, 50);
20+
diagramManager.AddLink(node1.GetPort(PortAlignment.Top), node2.GetPort(PortAlignment.Right));
21+
diagramManager.AddLink(node1.GetPort(PortAlignment.Bottom), node3.GetPort(PortAlignment.Top));
22+
diagramManager.AddNode(node1);
23+
diagramManager.AddNode(node2);
24+
diagramManager.AddNode(node3);
25+
}
26+
27+
28+
protected void ReconnectLinks() => diagramManager.ReconnectLinksToClosestPorts();
29+
30+
31+
private NodeModel NewNode(double x, double y)
32+
{
33+
var node = new NodeModel(new Point(x, y));
34+
node.AddPort(PortAlignment.Bottom);
35+
node.AddPort(PortAlignment.Top);
36+
node.AddPort(PortAlignment.Left);
37+
node.AddPort(PortAlignment.Right);
38+
return node;
39+
}
40+
}
41+
}

samples/SharedDemo/Layouts/DemoLayout.razor

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@
4545
<a href="demos/custom-node" class="list-group-item list-group-item-action bg-light">Custom node</a>
4646
<a href="demos/custom-link" class="list-group-item list-group-item-action bg-light">Custom link</a>
4747
<a href="demos/custom-port" class="list-group-item list-group-item-action bg-light">Custom port</a>
48+
49+
<div class="list-group-item bg-primary text-light">Algorithms</div>
50+
<a href="demos/reconnect-links" class="list-group-item list-group-item-action bg-light">Reconnect links</a>
4851
</div>
4952
</div>
5053
<div id="page-content-wrapper">

samples/SharedDemo/SharedDemo.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
</ItemGroup>
1212

1313
<ItemGroup>
14+
<ProjectReference Include="..\..\src\Blazor.Diagrams.Algorithms\Blazor.Diagrams.Algorithms.csproj" />
1415
<ProjectReference Include="..\..\src\Blazor.Diagrams.Core\Blazor.Diagrams.Core.csproj" />
1516
<ProjectReference Include="..\..\src\Blazor.Diagrams\Blazor.Diagrams.csproj" />
1617
</ItemGroup>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFramework>netstandard2.1</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
7+
<PackageLicenseExpression>MIT</PackageLicenseExpression>
8+
<Authors>zHaytam</Authors>
9+
<Description>A fully customizable and extensible all-purpose diagrams library for Blazor</Description>
10+
<AssemblyVersion>0.1</AssemblyVersion>
11+
<FileVersion>0.1</FileVersion>
12+
<RepositoryUrl>https://github.com/zHaytam/Blazor.Diagrams</RepositoryUrl>
13+
<Version>0.10</Version>
14+
<PackageId>Z.Blazor.Diagrams.Algorithms</PackageId>
15+
<PackageTags>blazor diagrams diagramming svg drag algorithms layouts</PackageTags>
16+
<Product>Z.Blazor.Diagrams.Algorithms</Product>
17+
</PropertyGroup>
18+
19+
<ItemGroup>
20+
<ProjectReference Include="..\Blazor.Diagrams.Core\Blazor.Diagrams.Core.csproj" />
21+
</ItemGroup>
22+
23+
</Project>
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using Blazor.Diagrams.Core.Models.Core;
2+
using System;
3+
4+
namespace Blazor.Diagrams.Algorithms.Extensions
5+
{
6+
public static class PointExtensions
7+
{
8+
public static double DistanceTo(this Point firstPoint, Point secondPoint)
9+
{
10+
var x = Math.Abs(firstPoint.X - secondPoint.X);
11+
var y = Math.Abs(firstPoint.Y - secondPoint.Y);
12+
return Math.Sqrt(x * x + y * y);
13+
}
14+
}
15+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
using Blazor.Diagrams.Algorithms.Extensions;
2+
using Blazor.Diagrams.Core;
3+
using Blazor.Diagrams.Core.Models;
4+
using System.Collections.Generic;
5+
using System.Linq;
6+
7+
namespace Blazor.Diagrams.Algorithms
8+
{
9+
public static class LinksReconnectionAlgorithms
10+
{
11+
public static void ReconnectLinksToClosestPorts(this DiagramManager diagramManager)
12+
{
13+
// Only refresh ports once
14+
var portsToRefresh = new HashSet<PortModel>();
15+
16+
foreach (var link in diagramManager.AllLinks.ToArray())
17+
{
18+
if (link.TargetPort == null)
19+
continue;
20+
21+
var sourcePorts = link.SourcePort.Parent.Ports;
22+
var targetPorts = link.TargetPort.Parent.Ports;
23+
24+
// Find the ports with minimal distance
25+
var minDistance = double.MaxValue;
26+
var minSourcePort = link.SourcePort;
27+
var minTargetPort = link.TargetPort;
28+
foreach (var sourcePort in sourcePorts)
29+
{
30+
foreach (var targetPort in targetPorts)
31+
{
32+
var distance = sourcePort.Position.DistanceTo(targetPort.Position);
33+
if (distance < minDistance)
34+
{
35+
minDistance = distance;
36+
minSourcePort = sourcePort;
37+
minTargetPort = targetPort;
38+
}
39+
}
40+
}
41+
42+
// Reconnect
43+
if (link.SourcePort != minSourcePort)
44+
{
45+
portsToRefresh.Add(link.SourcePort);
46+
portsToRefresh.Add(minSourcePort);
47+
link.SetSourcePort(minSourcePort);
48+
}
49+
50+
if (link.TargetPort != minTargetPort)
51+
{
52+
portsToRefresh.Add(link.TargetPort);
53+
portsToRefresh.Add(minTargetPort);
54+
link.SetTargetPort(minTargetPort);
55+
}
56+
}
57+
58+
foreach (var port in portsToRefresh)
59+
port.Refresh();
60+
}
61+
}
62+
}

src/Blazor.Diagrams.Core/DiagramManager.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,6 @@ public void AttachLink(LinkModel link, PortModel targetPort)
154154
return;
155155

156156
link.SetTargetPort(targetPort);
157-
targetPort.AddLink(link);
158157
link.Refresh();
159158
targetPort.Refresh();
160159
LinkAttached?.Invoke(link);

0 commit comments

Comments
 (0)