Skip to content

Commit ab54d55

Browse files
authored
Merge pull request #66 from zHaytam/develop
Version 1.5.0
2 parents 2d6a7aa + f0f1d3b commit ab54d55

23 files changed

+314
-139
lines changed

CHANGELOG.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## Diagrams [1.5.0] - 2021-01-05
8+
9+
## Added
10+
11+
- The ability to have ports on groups.
12+
- **EXPERIMENTAL/INCOMPLETE** Nested groups. Since `GroupModel` now inherits `NodeMode`, it became possible to have nested groups, but there are still problems with the order of links between groups.
13+
- A `Class` parameter to `GroupContainer`.
14+
15+
## Changed
16+
17+
- Only rerender groups when necessary.
18+
- Receiving the same size from `ResizeObserver` doesn't trigger a rerender anymore.
19+
- Avoid rerendering ports twice to update positions.
20+
- Avoid rerendering ports when their parent node is moving.
21+
- Padding is now handled in `GroupModel` instead of `GroupContainer` (UI). This is because the padding is necessary to have accurate size/position in the group model directly.
22+
23+
## Fixed
24+
25+
- Use `@key` when rendering the list of groups. Not using it caused big/weird render times.
26+
- Groups not showing in Navigator/Overview.
27+
728
## Diagrams [1.4.2] - 2020-12-30
829

930
## Added

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ You can get started very easily & quickly using:
4040
- Customizable Diagram Overview/Preview/Navigator (on the bottom right by default)
4141
- Snap to Grid
4242
- Grouping: [CTRL + ALT + G] to (un)group
43-
- Clipping: only draw nodes that are visible to the users
43+
- Groups with ports/links and nested groups (**experimental**)
44+
- Virtualization: only draw nodes that are visible to the users
4445
- Algorithms
4546

4647
## Preview

samples/SharedDemo/Demos/Grouping.razor.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,16 @@ protected override void OnInitialized()
1818

1919
var node1 = NewNode(50, 50);
2020
var node2 = NewNode(250, 250);
21-
var node3 = NewNode(450, 100);
21+
var node3 = NewNode(500, 100);
22+
23+
var group = diagramManager.Group(node1, node2);
24+
group.AddPort(PortAlignment.Bottom);
25+
group.AddPort(PortAlignment.Top);
26+
group.AddPort(PortAlignment.Left);
27+
group.AddPort(PortAlignment.Right);
2228

2329
diagramManager.AddLink(node1.GetPort(PortAlignment.Right), node2.GetPort(PortAlignment.Left));
24-
diagramManager.AddLink(node2.GetPort(PortAlignment.Right), node3.GetPort(PortAlignment.Left));
25-
diagramManager.Group(node1, node2);
30+
diagramManager.AddLink(group.GetPort(PortAlignment.Right), node3.GetPort(PortAlignment.Left));
2631
diagramManager.AddNode(node3);
2732
}
2833

src/Blazor.Diagrams.Core/Blazor.Diagrams.Core.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
<PackageLicenseExpression>MIT</PackageLicenseExpression>
88
<Authors>zHaytam</Authors>
99
<Description>A fully customizable and extensible all-purpose diagrams library for Blazor</Description>
10-
<AssemblyVersion>1.4.2</AssemblyVersion>
11-
<FileVersion>1.4.2</FileVersion>
10+
<AssemblyVersion>1.5.0</AssemblyVersion>
11+
<FileVersion>1.5.0</FileVersion>
1212
<RepositoryUrl>https://github.com/zHaytam/Blazor.Diagrams</RepositoryUrl>
13-
<Version>1.4.2</Version>
13+
<Version>1.5.0</Version>
1414
<PackageId>Z.Blazor.Diagrams.Core</PackageId>
1515
<PackageTags>blazor diagrams diagramming svg drag</PackageTags>
1616
<Product>Z.Blazor.Diagrams.Core</Product>

src/Blazor.Diagrams.Core/Default/GroupingSubManager.cs

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -20,36 +20,36 @@ private void DiagramManager_KeyDown(KeyboardEventArgs e)
2020
if (DiagramManager.SelectedModels.Count == 0)
2121
return;
2222

23-
if (e.CtrlKey && e.AltKey && e.Key.Equals("g", StringComparison.InvariantCultureIgnoreCase))
24-
{
25-
var selectedNodes = DiagramManager.SelectedModels
26-
.Where(m => m is NodeModel)
27-
.Select(m => (NodeModel)m)
28-
.ToArray();
23+
if (!e.CtrlKey || !e.AltKey || !e.Key.Equals("g", StringComparison.InvariantCultureIgnoreCase))
24+
return;
2925

30-
var nodesWithGroup = selectedNodes.Where(n => n.Group != null).ToArray();
31-
if (nodesWithGroup.Length > 0)
26+
var selectedNodes = DiagramManager.SelectedModels
27+
.Where(m => m is NodeModel)
28+
.Select(m => (NodeModel)m)
29+
.ToArray();
30+
31+
var nodesWithGroup = selectedNodes.Where(n => n.Group != null).ToArray();
32+
if (nodesWithGroup.Length > 0)
33+
{
34+
// Ungroup
35+
foreach (var group in nodesWithGroup.GroupBy(n => n.Group!).Select(g => g.Key))
3236
{
33-
// Ungroup
34-
foreach (var group in nodesWithGroup.GroupBy(n => n.Group!).Select(g => g.Key))
35-
{
36-
DiagramManager.Ungroup(group);
37-
}
37+
DiagramManager.Ungroup(group);
3838
}
39-
else
40-
{
41-
// Group
42-
if (selectedNodes.Length < 2)
43-
return;
39+
}
40+
else
41+
{
42+
// Group
43+
if (selectedNodes.Length < 2)
44+
return;
4445

45-
if (selectedNodes.Any(n => n.Group != null))
46-
return;
46+
if (selectedNodes.Any(n => n.Group != null))
47+
return;
4748

48-
if (selectedNodes.Select(n => n.Layer).Distinct().Count() > 1)
49-
return;
49+
if (selectedNodes.Select(n => n.Layer).Distinct().Count() > 1)
50+
return;
5051

51-
DiagramManager.Group(selectedNodes);
52-
}
52+
DiagramManager.Group(selectedNodes);
5353
}
5454
}
5555

src/Blazor.Diagrams.Core/DiagramManager.cs

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public DiagramManager(DiagramOptions? options = null)
6060
}
6161

6262
public IReadOnlyCollection<NodeModel> Nodes => _nodes;
63-
public IEnumerable<LinkModel> AllLinks => _nodes.SelectMany(n => n.AllLinks).Distinct();
63+
public IEnumerable<LinkModel> AllLinks => _nodes.SelectMany(n => n.AllLinks).Union(_groups.SelectMany(g => g.AllLinks)).Distinct();
6464
public IReadOnlyCollection<SelectableModel> SelectedModels => _selectedModels;
6565
public IReadOnlyCollection<GroupModel> Groups => _groups;
6666
public Rectangle? Container { get; internal set; }
@@ -140,6 +140,10 @@ public T AddLink<T>(T link, PortModel source, PortModel? target = null) where T
140140

141141
source.Refresh();
142142
target?.Refresh();
143+
144+
source.Parent.Group?.Refresh();
145+
target?.Parent.Group?.Refresh();
146+
143147
LinkAdded?.Invoke(link);
144148
Changed?.Invoke();
145149
return link;
@@ -156,6 +160,10 @@ public void AttachLink(LinkModel link, PortModel targetPort)
156160
link.SetTargetPort(targetPort);
157161
link.Refresh();
158162
targetPort.Refresh();
163+
164+
link.SourcePort.Parent.Group?.Refresh();
165+
targetPort?.Parent.Group?.Refresh();
166+
159167
LinkAttached?.Invoke(link);
160168
}
161169

@@ -168,32 +176,42 @@ public void RemoveLink(LinkModel link, bool triggerEvent = true)
168176
link.SourcePort.Refresh();
169177
link.TargetPort?.Refresh();
170178

179+
link.SourcePort.Parent.Group?.Refresh();
180+
link.TargetPort?.Parent.Group?.Refresh();
181+
171182
if (triggerEvent)
172183
{
173184
Changed?.Invoke();
174185
}
175186
}
176187

177-
public GroupModel Group(params NodeModel[] nodes)
188+
public GroupModel Group(params NodeModel[] children)
178189
{
179-
if (nodes.Length < 2)
190+
if (children.Length < 2)
180191
throw new ArgumentException("Number of nodes must be >= 2");
181192

182-
var layers = nodes.Select(n => n.Layer).Distinct();
193+
var layers = children.Select(n => n.Layer).Distinct();
183194
if (layers.Count() > 1)
184195
throw new InvalidOperationException("Cannot group nodes with different layers");
185196

186197
if (layers.First() == RenderLayer.SVG)
187198
throw new InvalidOperationException("SVG groups aren't imeplemtend yet");
188199

189-
if (nodes.Any(n => n.Group != null))
200+
if (children.Any(n => n.Group != null))
190201
throw new InvalidOperationException("Cannot group nodes that already belong to another group");
191202

192-
var group = new GroupModel(this, nodes);
203+
var group = new GroupModel(this, children);
193204

194-
foreach (var node in nodes)
205+
foreach (var child in children)
195206
{
196-
_nodes.Remove(node);
207+
if (child is GroupModel g)
208+
{
209+
_groups.Remove(g);
210+
}
211+
else
212+
{
213+
_nodes.Remove(child);
214+
}
197215
}
198216

199217
_groups.Add(group);
@@ -209,8 +227,17 @@ public void Ungroup(GroupModel group)
209227

210228
group.Ungroup();
211229

212-
foreach (var node in group.Children)
213-
_nodes.Add(node);
230+
foreach (var child in group.Children)
231+
{
232+
if (child is GroupModel g)
233+
{
234+
_groups.Add(g);
235+
}
236+
else
237+
{
238+
_nodes.Add(child);
239+
}
240+
}
214241

215242
GroupRemoved?.Invoke(group);
216243
Refresh();
@@ -295,7 +322,7 @@ public void RegisterModelComponent(Type modelType, Type componentType)
295322
}
296323

297324
public void Refresh() => Changed?.Invoke();
298-
325+
299326
public void ZoomToFit(double margin = 10)
300327
{
301328
if (_nodes.Count == 0)

src/Blazor.Diagrams.Core/Models/Core/Size.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public Size(double width, double height)
1717

1818
public Size Add(double value) => new Size(Width + value, Height + value);
1919

20-
public bool Equals(Size size) => size != null && Width == size.Width && Height == size.Height;
20+
public bool Equals(Size? size) => size != null && Width == size.Width && Height == size.Height;
2121

2222
public override string ToString() => $"Size(width={Width}, height={Height})";
2323
}
Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
1-
using Blazor.Diagrams.Core.Models.Base;
2-
using Blazor.Diagrams.Core.Models.Core;
1+
using Blazor.Diagrams.Core.Models.Core;
2+
using System;
33
using System.Collections.Generic;
44
using System.Linq;
55

66
namespace Blazor.Diagrams.Core.Models
77
{
8-
public class GroupModel : MovableModel
8+
public class GroupModel : NodeModel
99
{
1010
private readonly DiagramManager _diagramManager;
11+
private readonly byte _padding;
1112

12-
public GroupModel(DiagramManager diagramManager, NodeModel[] children)
13+
public GroupModel(DiagramManager diagramManager, NodeModel[] children, byte padding = 30)
1314
{
1415
_diagramManager = diagramManager;
16+
_padding = padding;
17+
18+
Size = Size.Zero;
1519
Children = children;
1620
Initialize();
1721
}
1822

1923
public NodeModel[] Children { get; private set; }
20-
public Size Size { get; private set; } = Size.Zero;
21-
22-
public IEnumerable<LinkModel> AllLinks => Children.SelectMany(n => n.AllLinks).Distinct();
24+
public IEnumerable<LinkModel> HandledLinks => Children.SelectMany(c => c.AllLinks).Distinct();
2325

2426
public override void SetPosition(double x, double y)
2527
{
@@ -33,42 +35,53 @@ public override void SetPosition(double x, double y)
3335
Refresh();
3436
}
3537

38+
public override void UpdatePositionSilently(double deltaX, double deltaY)
39+
{
40+
base.UpdatePositionSilently(deltaX, deltaY);
41+
42+
foreach (var child in Children)
43+
child.UpdatePositionSilently(deltaX, deltaY);
44+
}
45+
3646
public void Ungroup()
3747
{
38-
foreach (var node in Children)
48+
foreach (var child in Children)
3949
{
40-
node.Group = null;
41-
node.SizeChanged -= OnNodeChanged;
42-
node.Moving -= OnNodeChanged;
50+
child.Group = null;
51+
child.SizeChanged -= OnNodeChanged;
52+
child.Moving -= OnNodeChanged;
4353
}
4454
}
4555

4656
private void Initialize()
4757
{
48-
foreach (var node in Children)
58+
foreach (var child in Children)
4959
{
50-
node.Group = this;
51-
node.SizeChanged += OnNodeChanged;
52-
node.Moving += OnNodeChanged;
60+
child.Group = this;
61+
child.SizeChanged += OnNodeChanged;
62+
child.Moving += OnNodeChanged;
5363
}
5464

5565
UpdateDimensions();
5666
}
5767

5868
private void OnNodeChanged(NodeModel node)
5969
{
60-
UpdateDimensions();
61-
Refresh();
70+
if (UpdateDimensions())
71+
{
72+
Refresh();
73+
}
6274
}
6375

64-
private void UpdateDimensions()
76+
private bool UpdateDimensions()
6577
{
6678
if (Children.Any(n => n.Size == null))
67-
return;
79+
return false;
6880

6981
(var nodesMinX, var nodesMaxX, var nodesMinY, var nodesMaxY) = _diagramManager.GetNodesRect(Children);
70-
Size = new Size(nodesMaxX - nodesMinX, nodesMaxY - nodesMinY);
71-
Position = new Point(nodesMinX, nodesMinY);
82+
Size = new Size(nodesMaxX - nodesMinX + _padding * 2, nodesMaxY - nodesMinY + _padding * 2);
83+
Position = new Point(nodesMinX - _padding, nodesMinY - _padding);
84+
return true;
7285
}
7386
}
7487
}

0 commit comments

Comments
 (0)