Skip to content

Commit

Permalink
Merge pull request #66 from zHaytam/develop
Browse files Browse the repository at this point in the history
Version 1.5.0
  • Loading branch information
zHaytam authored Jan 5, 2021
2 parents 2d6a7aa + f0f1d3b commit ab54d55
Show file tree
Hide file tree
Showing 23 changed files with 314 additions and 139 deletions.
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,27 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## Diagrams [1.5.0] - 2021-01-05

## Added

- The ability to have ports on groups.
- **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.
- A `Class` parameter to `GroupContainer`.

## Changed

- Only rerender groups when necessary.
- Receiving the same size from `ResizeObserver` doesn't trigger a rerender anymore.
- Avoid rerendering ports twice to update positions.
- Avoid rerendering ports when their parent node is moving.
- 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.

## Fixed

- Use `@key` when rendering the list of groups. Not using it caused big/weird render times.
- Groups not showing in Navigator/Overview.

## Diagrams [1.4.2] - 2020-12-30

## Added
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ You can get started very easily & quickly using:
- Customizable Diagram Overview/Preview/Navigator (on the bottom right by default)
- Snap to Grid
- Grouping: [CTRL + ALT + G] to (un)group
- Clipping: only draw nodes that are visible to the users
- Groups with ports/links and nested groups (**experimental**)
- Virtualization: only draw nodes that are visible to the users
- Algorithms

## Preview
Expand Down
11 changes: 8 additions & 3 deletions samples/SharedDemo/Demos/Grouping.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,16 @@ protected override void OnInitialized()

var node1 = NewNode(50, 50);
var node2 = NewNode(250, 250);
var node3 = NewNode(450, 100);
var node3 = NewNode(500, 100);

var group = diagramManager.Group(node1, node2);
group.AddPort(PortAlignment.Bottom);
group.AddPort(PortAlignment.Top);
group.AddPort(PortAlignment.Left);
group.AddPort(PortAlignment.Right);

diagramManager.AddLink(node1.GetPort(PortAlignment.Right), node2.GetPort(PortAlignment.Left));
diagramManager.AddLink(node2.GetPort(PortAlignment.Right), node3.GetPort(PortAlignment.Left));
diagramManager.Group(node1, node2);
diagramManager.AddLink(group.GetPort(PortAlignment.Right), node3.GetPort(PortAlignment.Left));
diagramManager.AddNode(node3);
}

Expand Down
6 changes: 3 additions & 3 deletions src/Blazor.Diagrams.Core/Blazor.Diagrams.Core.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<Authors>zHaytam</Authors>
<Description>A fully customizable and extensible all-purpose diagrams library for Blazor</Description>
<AssemblyVersion>1.4.2</AssemblyVersion>
<FileVersion>1.4.2</FileVersion>
<AssemblyVersion>1.5.0</AssemblyVersion>
<FileVersion>1.5.0</FileVersion>
<RepositoryUrl>https://github.com/zHaytam/Blazor.Diagrams</RepositoryUrl>
<Version>1.4.2</Version>
<Version>1.5.0</Version>
<PackageId>Z.Blazor.Diagrams.Core</PackageId>
<PackageTags>blazor diagrams diagramming svg drag</PackageTags>
<Product>Z.Blazor.Diagrams.Core</Product>
Expand Down
48 changes: 24 additions & 24 deletions src/Blazor.Diagrams.Core/Default/GroupingSubManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,36 +20,36 @@ private void DiagramManager_KeyDown(KeyboardEventArgs e)
if (DiagramManager.SelectedModels.Count == 0)
return;

if (e.CtrlKey && e.AltKey && e.Key.Equals("g", StringComparison.InvariantCultureIgnoreCase))
{
var selectedNodes = DiagramManager.SelectedModels
.Where(m => m is NodeModel)
.Select(m => (NodeModel)m)
.ToArray();
if (!e.CtrlKey || !e.AltKey || !e.Key.Equals("g", StringComparison.InvariantCultureIgnoreCase))
return;

var nodesWithGroup = selectedNodes.Where(n => n.Group != null).ToArray();
if (nodesWithGroup.Length > 0)
var selectedNodes = DiagramManager.SelectedModels
.Where(m => m is NodeModel)
.Select(m => (NodeModel)m)
.ToArray();

var nodesWithGroup = selectedNodes.Where(n => n.Group != null).ToArray();
if (nodesWithGroup.Length > 0)
{
// Ungroup
foreach (var group in nodesWithGroup.GroupBy(n => n.Group!).Select(g => g.Key))
{
// Ungroup
foreach (var group in nodesWithGroup.GroupBy(n => n.Group!).Select(g => g.Key))
{
DiagramManager.Ungroup(group);
}
DiagramManager.Ungroup(group);
}
else
{
// Group
if (selectedNodes.Length < 2)
return;
}
else
{
// Group
if (selectedNodes.Length < 2)
return;

if (selectedNodes.Any(n => n.Group != null))
return;
if (selectedNodes.Any(n => n.Group != null))
return;

if (selectedNodes.Select(n => n.Layer).Distinct().Count() > 1)
return;
if (selectedNodes.Select(n => n.Layer).Distinct().Count() > 1)
return;

DiagramManager.Group(selectedNodes);
}
DiagramManager.Group(selectedNodes);
}
}

Expand Down
49 changes: 38 additions & 11 deletions src/Blazor.Diagrams.Core/DiagramManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public DiagramManager(DiagramOptions? options = null)
}

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

source.Refresh();
target?.Refresh();

source.Parent.Group?.Refresh();
target?.Parent.Group?.Refresh();

LinkAdded?.Invoke(link);
Changed?.Invoke();
return link;
Expand All @@ -156,6 +160,10 @@ public void AttachLink(LinkModel link, PortModel targetPort)
link.SetTargetPort(targetPort);
link.Refresh();
targetPort.Refresh();

link.SourcePort.Parent.Group?.Refresh();
targetPort?.Parent.Group?.Refresh();

LinkAttached?.Invoke(link);
}

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

link.SourcePort.Parent.Group?.Refresh();
link.TargetPort?.Parent.Group?.Refresh();

if (triggerEvent)
{
Changed?.Invoke();
}
}

public GroupModel Group(params NodeModel[] nodes)
public GroupModel Group(params NodeModel[] children)
{
if (nodes.Length < 2)
if (children.Length < 2)
throw new ArgumentException("Number of nodes must be >= 2");

var layers = nodes.Select(n => n.Layer).Distinct();
var layers = children.Select(n => n.Layer).Distinct();
if (layers.Count() > 1)
throw new InvalidOperationException("Cannot group nodes with different layers");

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

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

var group = new GroupModel(this, nodes);
var group = new GroupModel(this, children);

foreach (var node in nodes)
foreach (var child in children)
{
_nodes.Remove(node);
if (child is GroupModel g)
{
_groups.Remove(g);
}
else
{
_nodes.Remove(child);
}
}

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

group.Ungroup();

foreach (var node in group.Children)
_nodes.Add(node);
foreach (var child in group.Children)
{
if (child is GroupModel g)
{
_groups.Add(g);
}
else
{
_nodes.Add(child);
}
}

GroupRemoved?.Invoke(group);
Refresh();
Expand Down Expand Up @@ -295,7 +322,7 @@ public void RegisterModelComponent(Type modelType, Type componentType)
}

public void Refresh() => Changed?.Invoke();

public void ZoomToFit(double margin = 10)
{
if (_nodes.Count == 0)
Expand Down
2 changes: 1 addition & 1 deletion src/Blazor.Diagrams.Core/Models/Core/Size.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public Size(double width, double height)

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

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

public override string ToString() => $"Size(width={Width}, height={Height})";
}
Expand Down
55 changes: 34 additions & 21 deletions src/Blazor.Diagrams.Core/Models/GroupModel.cs
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
using Blazor.Diagrams.Core.Models.Base;
using Blazor.Diagrams.Core.Models.Core;
using Blazor.Diagrams.Core.Models.Core;
using System;
using System.Collections.Generic;
using System.Linq;

namespace Blazor.Diagrams.Core.Models
{
public class GroupModel : MovableModel
public class GroupModel : NodeModel
{
private readonly DiagramManager _diagramManager;
private readonly byte _padding;

public GroupModel(DiagramManager diagramManager, NodeModel[] children)
public GroupModel(DiagramManager diagramManager, NodeModel[] children, byte padding = 30)
{
_diagramManager = diagramManager;
_padding = padding;

Size = Size.Zero;
Children = children;
Initialize();
}

public NodeModel[] Children { get; private set; }
public Size Size { get; private set; } = Size.Zero;

public IEnumerable<LinkModel> AllLinks => Children.SelectMany(n => n.AllLinks).Distinct();
public IEnumerable<LinkModel> HandledLinks => Children.SelectMany(c => c.AllLinks).Distinct();

public override void SetPosition(double x, double y)
{
Expand All @@ -33,42 +35,53 @@ public override void SetPosition(double x, double y)
Refresh();
}

public override void UpdatePositionSilently(double deltaX, double deltaY)
{
base.UpdatePositionSilently(deltaX, deltaY);

foreach (var child in Children)
child.UpdatePositionSilently(deltaX, deltaY);
}

public void Ungroup()
{
foreach (var node in Children)
foreach (var child in Children)
{
node.Group = null;
node.SizeChanged -= OnNodeChanged;
node.Moving -= OnNodeChanged;
child.Group = null;
child.SizeChanged -= OnNodeChanged;
child.Moving -= OnNodeChanged;
}
}

private void Initialize()
{
foreach (var node in Children)
foreach (var child in Children)
{
node.Group = this;
node.SizeChanged += OnNodeChanged;
node.Moving += OnNodeChanged;
child.Group = this;
child.SizeChanged += OnNodeChanged;
child.Moving += OnNodeChanged;
}

UpdateDimensions();
}

private void OnNodeChanged(NodeModel node)
{
UpdateDimensions();
Refresh();
if (UpdateDimensions())
{
Refresh();
}
}

private void UpdateDimensions()
private bool UpdateDimensions()
{
if (Children.Any(n => n.Size == null))
return;
return false;

(var nodesMinX, var nodesMaxX, var nodesMinY, var nodesMaxY) = _diagramManager.GetNodesRect(Children);
Size = new Size(nodesMaxX - nodesMinX, nodesMaxY - nodesMinY);
Position = new Point(nodesMinX, nodesMinY);
Size = new Size(nodesMaxX - nodesMinX + _padding * 2, nodesMaxY - nodesMinY + _padding * 2);
Position = new Point(nodesMinX - _padding, nodesMinY - _padding);
return true;
}
}
}
Loading

0 comments on commit ab54d55

Please sign in to comment.