Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Tested with Mermaid js v9.1.1
- [x] [Class diagram](https://mermaid-js.github.io/mermaid/#/classDiagram)
- [x] [Pie chart](https://mermaid-js.github.io/mermaid/#/pie)
- [x] [State diagram](https://mermaid-js.github.io/mermaid/#/stateDiagram)
- [ ] [Entity relationship](https://mermaid-js.github.io/mermaid/#/entityRelationshipDiagram) https://github.com/wowbios/FluentMermaid/issues/18
- [x] [Entity relationship](https://mermaid-js.github.io/mermaid/#/entityRelationshipDiagram) https://github.com/wowbios/FluentMermaid/issues/18
- [ ] [User journey](https://mermaid-js.github.io/mermaid/#/user-journey) https://github.com/wowbios/FluentMermaid/issues/19
- [ ] [Gantt](https://mermaid-js.github.io/mermaid/#/gantt) https://github.com/wowbios/FluentMermaid/issues/20
- [ ] [Requirement](https://mermaid-js.github.io/mermaid/#/requirementDiagram) https://github.com/wowbios/FluentMermaid/issues/21
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using FluentMermaid.EntityRelationship.Interfaces;
using FluentMermaid.EntityRelationship.Nodes;

namespace FluentMermaid.EntityRelationship;

public static class EntityRelationshipDiagram
{
public static IEntityRelationshipDiagram Create() => new EntityRelationshipDiagramRoot();
}
9 changes: 9 additions & 0 deletions src/FluentMermaid/EntityRelationship/Enums/Cardinality.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace FluentMermaid.EntityRelationship.Enums;

public enum Cardinality
{
ZeroOrOne,
OnlyOne,
ZeroOrMany,
OneOrMany
}
7 changes: 7 additions & 0 deletions src/FluentMermaid/EntityRelationship/Enums/RelationType.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace FluentMermaid.EntityRelationship.Enums;

public enum RelationType
{
Identifying,
NonIdentifying
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using FluentMermaid.EntityRelationship.Enums;

namespace FluentMermaid.EntityRelationship.Extensions;

internal static class CardinalityExtensions
{
public static string Render(this Cardinality cardinality, bool left)
=> cardinality switch
{
Cardinality.ZeroOrOne => left ? "o|" : "|o",
Cardinality.OnlyOne => "||",
Cardinality.ZeroOrMany => left ? "}o" : "o{",
Cardinality.OneOrMany => left ? "}|" : "|{",
_ => throw new ArgumentOutOfRangeException(nameof(cardinality), cardinality, null)
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using FluentMermaid.EntityRelationship.Enums;

namespace FluentMermaid.EntityRelationship.Extensions;

internal static class RelationTypeExtensions
{
public static string Render(this RelationType type)
=> type switch
{
RelationType.Identifying => "--",
RelationType.NonIdentifying => "..",
_ => throw new ArgumentOutOfRangeException(nameof(type), type, null)
};
}
9 changes: 9 additions & 0 deletions src/FluentMermaid/EntityRelationship/Interfaces/IEntity.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using System.Text;

namespace FluentMermaid.EntityRelationship.Interfaces;

public interface IEntity : IRenderTo<StringBuilder>
{
string Name { get; }
IField AddField(string type, string name, string? modifier);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using FluentMermaid.EntityRelationship.Enums;

namespace FluentMermaid.EntityRelationship.Interfaces;

public interface IEntityRelationshipDiagram
{
IEntity AddEntity(string name);
IRelation Relation(IEntity from, IEntity to, Cardinality fromCardinality, Cardinality toCardinality, RelationType relationType, string? label);
string Render();
}
10 changes: 10 additions & 0 deletions src/FluentMermaid/EntityRelationship/Interfaces/IField.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using System.Text;

namespace FluentMermaid.EntityRelationship.Interfaces;

public interface IField : IRenderTo<StringBuilder>
{
string Type { get; }
string Name { get; }
string? Modifier { get; }
}
14 changes: 14 additions & 0 deletions src/FluentMermaid/EntityRelationship/Interfaces/IRelation.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System.Text;
using FluentMermaid.EntityRelationship.Enums;

namespace FluentMermaid.EntityRelationship.Interfaces;

public interface IRelation : IRenderTo<StringBuilder>
{
IEntity From { get; }
IEntity To { get; }
Cardinality FromCardinality { get; }
Cardinality ToCardinality { get; }
RelationType RelationType { get; }
string? Label { get; }
}
31 changes: 31 additions & 0 deletions src/FluentMermaid/EntityRelationship/Nodes/EntityNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using System.Text;
using FluentMermaid.EntityRelationship.Interfaces;

namespace FluentMermaid.EntityRelationship.Nodes;

internal class EntityNode : IEntity
{
private readonly List<IField> _fields = new();

public EntityNode(string name)
{
Name = name ?? throw new ArgumentNullException(nameof(name));
}

public string Name { get; }

public IField AddField(string type, string name, string? modifier)
{
var field = new FieldNode(type, name, modifier);
_fields.Add(field);
return field;
}

public void RenderTo(StringBuilder builder)
{
builder.AppendLine($"{Name} {{");
foreach (IField field in _fields)
field.RenderTo(builder);
builder.AppendLine("}");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Text;
using FluentMermaid.EntityRelationship.Enums;
using FluentMermaid.EntityRelationship.Interfaces;

namespace FluentMermaid.EntityRelationship.Nodes;

internal class EntityRelationshipDiagramRoot : IEntityRelationshipDiagram
{
private readonly List<IEntity> _entities = new();
private readonly List<IRelation> _relations = new();

public IEntity AddEntity(string name)
{
var entity = new EntityNode(name);
_entities.Add(entity);
return entity;
}

public IRelation Relation(IEntity from, IEntity to, Cardinality fromCardinality, Cardinality toCardinality, RelationType relationType, string? label)
{
var relation = new RelationNode(from, to, fromCardinality, toCardinality, relationType, label);
_relations.Add(relation);
return relation;
}

public string Render()
{
var builder = new StringBuilder();
builder.AppendLine("erDiagram");
foreach (IEntity entity in _entities)
entity.RenderTo(builder);
foreach (IRelation relation in _relations)
relation.RenderTo(builder);
return builder.ToString();
}
}
19 changes: 19 additions & 0 deletions src/FluentMermaid/EntityRelationship/Nodes/FieldNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
using System.Text;
using FluentMermaid.EntityRelationship.Interfaces;

namespace FluentMermaid.EntityRelationship.Nodes;

internal record FieldNode(string Type, string Name, string? Modifier) : IField

Check failure on line 6 in src/FluentMermaid/EntityRelationship/Nodes/FieldNode.cs

View workflow job for this annotation

GitHub Actions / build

Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported

Check failure on line 6 in src/FluentMermaid/EntityRelationship/Nodes/FieldNode.cs

View workflow job for this annotation

GitHub Actions / build

Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported

Check failure on line 6 in src/FluentMermaid/EntityRelationship/Nodes/FieldNode.cs

View workflow job for this annotation

GitHub Actions / build

Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported

Check failure on line 6 in src/FluentMermaid/EntityRelationship/Nodes/FieldNode.cs

View workflow job for this annotation

GitHub Actions / build

Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported

Check failure on line 6 in src/FluentMermaid/EntityRelationship/Nodes/FieldNode.cs

View workflow job for this annotation

GitHub Actions / build

Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported

Check failure on line 6 in src/FluentMermaid/EntityRelationship/Nodes/FieldNode.cs

View workflow job for this annotation

GitHub Actions / build

Predefined type 'System.Runtime.CompilerServices.IsExternalInit' is not defined or imported
{
public void RenderTo(StringBuilder builder)
{
builder
.Append(' ') // indentation
.Append(Type)
.Append(' ')
.Append(Name);
if (!string.IsNullOrWhiteSpace(Modifier))
builder.Append(' ').Append(Modifier);
builder.AppendLine();
}
}
41 changes: 41 additions & 0 deletions src/FluentMermaid/EntityRelationship/Nodes/RelationNode.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System.Text;
using FluentMermaid.EntityRelationship.Enums;
using FluentMermaid.EntityRelationship.Extensions;
using FluentMermaid.EntityRelationship.Interfaces;

namespace FluentMermaid.EntityRelationship.Nodes;

internal class RelationNode : IRelation
{
public RelationNode(IEntity from, IEntity to, Cardinality fromCardinality, Cardinality toCardinality, RelationType relationType, string? label)
{
From = from;
To = to;
FromCardinality = fromCardinality;
ToCardinality = toCardinality;
RelationType = relationType;
Label = label;
}

public IEntity From { get; }
public IEntity To { get; }
public Cardinality FromCardinality { get; }
public Cardinality ToCardinality { get; }
public RelationType RelationType { get; }
public string? Label { get; }

public void RenderTo(StringBuilder builder)
{
builder
.Append(From.Name)
.Append(' ')
.Append(FromCardinality.Render(true))
.Append(RelationType.Render())
.Append(ToCardinality.Render(false))
.Append(' ')
.Append(To.Name);
if (!string.IsNullOrWhiteSpace(Label))
builder.Append(" : ").Append(Label);
builder.AppendLine();
}
}
Loading