Skip to content

Commit

Permalink
Merge pull request #69 from zHaytam/develop
Browse files Browse the repository at this point in the history
Version 1.5.1
  • Loading branch information
zHaytam authored Jan 9, 2021
2 parents ab54d55 + 8469fc5 commit 49311ac
Show file tree
Hide file tree
Showing 15 changed files with 262 additions and 22 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ 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.1] - 2021-01-09

## Added

- `AddGroup`: add an instance of a group to the diagram.
- Custom group documentation/demo.

## Fixed

- Clicking the canvas in the Events demo throws an exception.

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

## Added
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ You can get started very easily & quickly using:
</CascadingValue>
```

![](https://i.imgur.com/k4UThmh.png)
![](https://i.imgur.com/WZYL2PW.png)


### Sample project
Expand Down
117 changes: 117 additions & 0 deletions samples/SharedDemo/Customization.razor
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,117 @@ private NodeModel NewNode(double x, double y)
</p>
</div>
</section>
<section id="custom-groups" class="doc-section">
<h2 class="section-title">Custom groups</h2>
<p>
Creating custom groups is almost the same as creating custom nodes, except for some specifics.
</p>
<div id="create-group-model" class="section-block">
<h3 class="block-title">Creating a model</h3>
<p>
First, we'll create a new model for our group.
</p>
<pre><code class="language-csharp line-numbers">public class CustomGroupModel : GroupModel
{
public CustomGroupModel(DiagramManager diagramManager, NodeModel[] children, string title, byte padding = 30)
: base(diagramManager, children, padding)
{
Title = title;
}

public string Title { get; }
}</code></pre>
<p>
You can add whatever properties you might need. You can also change the value of the padding, which is used when calculating the position/size of the group.
</p>
</div>
<div id="create-group-component" class="section-block">
<h3 class="block-title">Creating a component</h3>
<p>
Second, we'll create a component <code>CustomGroupWidget</code> that handles our new type of links.
</p>
<pre><code class="language-markup line-numbers">&lt;GroupContainer Group=&quot;Group&quot; Class=&quot;custom&quot;&gt;
&lt;span class=&quot;title&quot;&gt;@@Group.Title&lt;/span&gt;
&lt;GroupLinks&gt;&lt;/GroupLinks&gt;
&lt;GroupNodes&gt;&lt;/GroupNodes&gt;

@@foreach (var port in Group.Ports)
{
&lt;PortRenderer Port=&quot;port&quot; Class=&quot;group-port&quot;&gt;&lt;/PortRenderer&gt;
}
&lt;/GroupContainer&gt;

@@code {
[Parameter] public CustomGroupModel Group { get; set; }
}</code></pre>
<ul>
<li>It is mandatory to wrap everything in a <code>GroupContainer</code> component so that everything works properly, such as the group's position, moving it, etc..</li>
<li>
It is mandatory to add both <code>GroupLinks</code> and <code>GroupNodes</code> as direct children of the container.
This will render the appropriate layers and populate/configure them properly.
</li>
<li>As with custom nodes, you are in charge of rendering the ports.</li>
</ul>

For any custom content, you can add it wherever you want, as long as it's inside the container like our title <code>span</code>.<br />
As with everything else, the component can be styled using CSS. Here is the styling of the custom group in the demos:
<pre><code class="language-css line-numbers">.group.custom {
outline: 2px solid black;
background-color: #6fbb6e;
}

.group.custom > span.title {
padding: 20px;
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
background: #eee;
border: 2px solid black;
border-radius: 50%;
background-color: #6fbb6e;
font-weight: bold;
text-transform: uppercase;
}</code></pre>
</div>
<div id="register-custom-group" class="section-block">
<h3 class="block-title">Registering the custom group</h3>
<p>
Lastly, we'll register the custom link and its component in the <code>DiagramManager</code>:
</p>
<pre><code class="language-csharp line-numbers">protected override void OnInitialized()
{
base.OnInitialized();

_diagramManager.RegisterModelComponent&lt;CustomGroupModel, CustomGroupWidget&gt;();

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

_diagramManager.AddNode(node1);
// You can create your own group directly and add it
// You don't have to add its children to the diagram
_diagramManager.AddGroup(new CustomGroupModel(_diagramManager, new[] { node2, node3 }, &quot;Group 1&quot;));

_diagramManager.AddLink(node1.GetPort(PortAlignment.Right), node2.GetPort(PortAlignment.Left));
_diagramManager.AddLink(node2.GetPort(PortAlignment.Right), node3.GetPort(PortAlignment.Bottom));
}

private NodeModel NewNode(double x, double y)
{
var node = new NodeModel(new Point(x, y));
node.AddPort(PortAlignment.Bottom);
node.AddPort(PortAlignment.Top);
node.AddPort(PortAlignment.Left);
node.AddPort(PortAlignment.Right);
return node;
}</code></pre>
</div>
<p>
Here's how it would look like:
</p>
<img src="_content/SharedDemo/img/CustomGroupDisplay.png" alt="Custom Group Display" />
</section>
</div>
</div>

Expand All @@ -301,6 +412,12 @@ private NodeModel NewNode(double x, double y)
<a class="nav-link scrollto" href="#create-link-component">Creating a component</a>
<a class="nav-link scrollto" href="#register-custom-link">Registering the custom link</a>
</nav>
<a class="nav-link scrollto" href="#custom-groups">Custom groups</a>
<nav class="doc-sub-menu nav flex-column">
<a class="nav-link scrollto" href="#create-group-model">Creating a model</a>
<a class="nav-link scrollto" href="#create-group-component">Creating a component</a>
<a class="nav-link scrollto" href="#register-custom-group">Registering the custom group</a>
</nav>
</nav>
</div>
</div>
16 changes: 16 additions & 0 deletions samples/SharedDemo/Demos/CustomGroup/CustomGroupModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using Blazor.Diagrams.Core;
using Blazor.Diagrams.Core.Models;

namespace SharedDemo.Demos.CustomGroup
{
public class CustomGroupModel : GroupModel
{
public CustomGroupModel(DiagramManager diagramManager, NodeModel[] children, string title, byte padding = 30)
: base(diagramManager, children, padding)
{
Title = title;
}

public string Title { get; }
}
}
9 changes: 9 additions & 0 deletions samples/SharedDemo/Demos/CustomGroup/CustomGroupWidget.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<GroupContainer Group="Group" Class="custom">
<span class="title">@Group.Title</span>
<GroupLinks></GroupLinks>
<GroupNodes></GroupNodes>
</GroupContainer>

@code {
[Parameter] public CustomGroupModel Group { get; set; }
}
7 changes: 7 additions & 0 deletions samples/SharedDemo/Demos/CustomGroup/Demo.razor
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@page "/demos/custom-group"
@layout DemoLayout
@inject LayoutData LayoutData

<CascadingValue Name="DiagramManager" Value="_diagramManager">
<DiagramCanvas></DiagramCanvas>
</CascadingValue>
42 changes: 42 additions & 0 deletions samples/SharedDemo/Demos/CustomGroup/Demo.razor.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using Blazor.Diagrams.Core;
using Blazor.Diagrams.Core.Models;
using Blazor.Diagrams.Core.Models.Core;

namespace SharedDemo.Demos.CustomGroup
{
partial class Demo
{
private readonly DiagramManager _diagramManager = new DiagramManager();

protected override void OnInitialized()
{
base.OnInitialized();

LayoutData.Title = "Custom group";
LayoutData.Info = "Creating your own custom groups is very easy!";
LayoutData.DataChanged();

_diagramManager.RegisterModelComponent<CustomGroupModel, CustomGroupWidget>();

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

_diagramManager.AddNode(node1);
_diagramManager.AddGroup(new CustomGroupModel(_diagramManager, new[] { node2, node3 }, "Group 1"));

_diagramManager.AddLink(node1.GetPort(PortAlignment.Right), node2.GetPort(PortAlignment.Left));
_diagramManager.AddLink(node2.GetPort(PortAlignment.Right), node3.GetPort(PortAlignment.Bottom));
}

private NodeModel NewNode(double x, double y)
{
var node = new NodeModel(new Point(x, y));
node.AddPort(PortAlignment.Bottom);
node.AddPort(PortAlignment.Top);
node.AddPort(PortAlignment.Left);
node.AddPort(PortAlignment.Right);
return node;
}
}
}
6 changes: 3 additions & 3 deletions samples/SharedDemo/Demos/Events.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@ private void RegisterEvents()

diagramManager.LinkRemoved += (l) => events.Add($"LinkRemoved, LinkId={l.Id}");

diagramManager.MouseUp += (m, e) => {
events.Add($"NodeMoved, NodeId={m.Id}");
diagramManager.MouseUp += (m, e) =>
{
events.Add($"MouseUp, ModelId={m?.Id}");
StateHasChanged();
};

}

private NodeModel NewNode(double x, double y)
Expand Down
1 change: 1 addition & 0 deletions samples/SharedDemo/Layouts/DemoLayout.razor
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
<a href="demos/custom-node" class="list-group-item list-group-item-action bg-light">Custom node</a>
<a href="demos/custom-link" class="list-group-item list-group-item-action bg-light">Custom link</a>
<a href="demos/custom-port" class="list-group-item list-group-item-action bg-light">Custom port</a>
<a href="demos/custom-group" class="list-group-item list-group-item-action bg-light">Custom group</a>

<div class="list-group-item bg-primary text-light">Algorithms</div>
<a href="demos/reconnect-links" class="list-group-item list-group-item-action bg-light">Reconnect links</a>
Expand Down
3 changes: 2 additions & 1 deletion samples/SharedDemo/_Imports.razor
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Blazor.Diagrams.Core.Extensions;
@using Blazor.Diagrams.Components.Renderers;
@using Blazor.Diagrams.Components.Renderers;
@using Blazor.Diagrams.Components.Groups;
20 changes: 19 additions & 1 deletion samples/SharedDemo/wwwroot/css/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -1614,4 +1614,22 @@ body {

.bg-primary {
background: #40babd !important;
}
}

.group.custom {
outline: 2px solid black;
background-color: #6fbb6e;
}

.group.custom > span.title {
padding: 20px;
position: absolute;
left: 50%;
transform: translate(-50%, -50%);
background: #eee;
border: 2px solid black;
border-radius: 50%;
background-color: #6fbb6e;
font-weight: bold;
text-transform: uppercase;
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
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.5.0</AssemblyVersion>
<FileVersion>1.5.0</FileVersion>
<AssemblyVersion>1.5.1</AssemblyVersion>
<FileVersion>1.5.1</FileVersion>
<RepositoryUrl>https://github.com/zHaytam/Blazor.Diagrams</RepositoryUrl>
<Version>1.5.0</Version>
<Version>1.5.1</Version>
<PackageId>Z.Blazor.Diagrams.Core</PackageId>
<PackageTags>blazor diagrams diagramming svg drag</PackageTags>
<Product>Z.Blazor.Diagrams.Core</Product>
Expand Down
38 changes: 28 additions & 10 deletions src/Blazor.Diagrams.Core/DiagramManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,11 @@ public LinkModel AddLink(PortModel source, PortModel? target = null)
return AddLink<LinkModel>(source, target);
}

/// <summary>
/// Creates and configures an instance of a link model that expects a constructor with two parameters:
/// the source port and the target port.
/// </summary>
/// <returns>The created link instance.</returns>
public T AddLink<T>(PortModel source, PortModel? target = null) where T : LinkModel
{
var link = (T)Activator.CreateInstance(typeof(T), source, target);
Expand Down Expand Up @@ -185,24 +190,38 @@ public void RemoveLink(LinkModel link, bool triggerEvent = true)
}
}

/// <summary>
/// Groups 2 or more children.
/// </summary>
/// <param name="children">An array of child nodes.</param>
/// <returns>The created group instance.</returns>
public GroupModel Group(params NodeModel[] children)
{
if (children.Length < 2)
if (children.Any(n => n.Group != null))
throw new InvalidOperationException("Cannot group nodes that already belong to another group");

var group = new GroupModel(this, children);
AddGroup(group);
return group;
}

/// <summary>
/// Adds the group to the diagram after validating it.
/// </summary>
/// <param name="group">A group instance.</param>
public void AddGroup(GroupModel group)
{
if (group.Children.Length < 2)
throw new ArgumentException("Number of nodes must be >= 2");

var layers = children.Select(n => n.Layer).Distinct();
var layers = group.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");
throw new InvalidOperationException("SVG groups aren't implemented yet");

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

var group = new GroupModel(this, children);

foreach (var child in children)
foreach (var child in group.Children)
{
if (child is GroupModel g)
{
Expand All @@ -217,7 +236,6 @@ public GroupModel Group(params NodeModel[] children)
_groups.Add(group);
GroupAdded?.Invoke(group);
Refresh();
return group;
}

public void Ungroup(GroupModel group)
Expand Down
6 changes: 3 additions & 3 deletions src/Blazor.Diagrams/Blazor.Diagrams.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
<RazorLangVersion>3.0</RazorLangVersion>
<Authors>zHaytam</Authors>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<AssemblyVersion>1.5.0</AssemblyVersion>
<FileVersion>1.5.0</FileVersion>
<AssemblyVersion>1.5.1</AssemblyVersion>
<FileVersion>1.5.1</FileVersion>
<RepositoryUrl>https://github.com/zHaytam/Blazor.Diagrams</RepositoryUrl>
<Description>A fully customizable and extensible all-purpose diagrams library for Blazor</Description>
<Version>1.5.0</Version>
<Version>1.5.1</Version>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<PackageTags>blazor diagrams diagramming svg drag</PackageTags>
<PackageId>Z.Blazor.Diagrams</PackageId>
Expand Down

0 comments on commit 49311ac

Please sign in to comment.