Skip to content

Commit

Permalink
Merge pull request #54 from 8T4/features/new-builders-and-themes
Browse files Browse the repository at this point in the history
Features/new builders and themes
  • Loading branch information
yanjustino authored Mar 17, 2024
2 parents 5c79196 + 4098c73 commit 0755359
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 23 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ on:
branches: [ main ]

env:
VERSION: 6.3.${{ github.run_number }}
CLI_VERSION: 2.3.${{ github.run_number }}
VERSION: 7.0.${{ github.run_number }}
CLI_VERSION: 3.0.${{ github.run_number }}
NUGET_INDEX: https://api.nuget.org/v3/index.json
BUILD_TYPE: Release

Expand Down
113 changes: 107 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ This package is available through [Nuget Packages](https://www.nuget.org/package
|`C4SHARP`| dotnet library for building diagrams | [![NuGet](https://img.shields.io/nuget/v/C4Sharp.svg)](https://www.nuget.org/packages/C4Sharp) | [![Nuget](https://img.shields.io/nuget/dt/C4Sharp.svg)](https://www.nuget.org/packages/C4Sharp) | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/51ea16a0d91548cb9e84bd6ab3e8cb9e)](https://www.codacy.com/gh/8T4/c4sharp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=8T4/c4sharp&utm_campaign=Badge_Grade) | [![.NET](https://github.com/8T4/c4sharp/actions/workflows/dotnet.yml/badge.svg)](https://github.com/8T4/c4sharp/actions/workflows/dotnet.yml) |
|`C4SCLI` | cli for compiling C4S projects | [![NuGet](https://img.shields.io/nuget/v/c4scli.svg)](https://www.nuget.org/packages/c4scli) | [![Nuget](https://img.shields.io/nuget/dt/c4scli.svg)](https://www.nuget.org/packages/c4scli) | [![Codacy Badge](https://app.codacy.com/project/badge/Grade/51ea16a0d91548cb9e84bd6ab3e8cb9e)](https://www.codacy.com/gh/8T4/c4sharp/dashboard?utm_source=github.com&utm_medium=referral&utm_content=8T4/c4sharp&utm_campaign=Badge_Grade) | [![.NET](https://github.com/8T4/c4sharp/actions/workflows/dotnet.yml/badge.svg)](https://github.com/8T4/c4sharp/actions/workflows/dotnet.yml) |

To build a diagram using the C4S library we need to identify the structures and their relationships through a class that inherits properties directly from DiagramBuildRunner. See the following example of building a container diagram:

### Create a new diagram from scratch
To build a diagram using the C4S library we need to identify the structures and their relationships through a class that inherits properties directly from `DiagramBuilder` (_ContainerDiagram, ComponentDiagram, ContextDiagram, SequenceDiagram, DeploymentDiagram_). See the following example of building a container diagram:


```C#
public class ContainerDiagramSample : ContainerDiagram
Expand Down Expand Up @@ -83,13 +86,63 @@ public class ContainerDiagramSample : ContainerDiagram
};
}
```
The following code shows how to compile the diagram:

### Create a new diagram from existing code

you can create structures that will be used in the diagram, as in the following example:

```c#

There are two strategies for compiling diagrams in your project: self-compiling and using the `C4SCLI` tool.
//Person
public static Person Customer => new ("customer", "Personal Banking Customer",
"A customer of the bank, with personal bank accounts.", Boundary.External);

public static Person InternalCustomer => new Person("internalcustomer", "Personal Banking Customer",
"An customer of the bank, with personal bank accounts.");

public static Person Manager => new ("manager", "Manager Banking Customer",
"A manager of the bank, with personal bank accounts.");

//SoftwareSystem
public static SoftwareSystem BankingSystem => new("BankingSystem", "Internet Banking System",
"Allows customers to view information about their bank accounts, and make payments.");

public static SoftwareSystem Mainframe => new("Mainframe", "Mainframe Banking System",
"Stores all of the core banking information about customers, accounts, transactions, etc.", Boundary.External);

public static SoftwareSystem MailSystem => new ("MailSystem", "E-mail system",
"The internal Microsoft Exchange e-mail system.", Boundary.External);


```

```c#
public class ContextDiagramSample : ContextDiagram
{
protected override string Title => "Component diagram for Internet Banking System";

protected override IEnumerable<Structure> Structures => new Structure[]
{
Customer,
BankingSystem,
Mainframe,
MailSystem
};

protected override IEnumerable<Relationship> Relationships => new[]
{
Customer > BankingSystem,
Customer < MailSystem | "Sends e-mails to",
BankingSystem > MailSystem | ("Sends e-mails", "SMTP") | Neighbor,
BankingSystem > Mainframe
};
}
```
### Compiling the diagram
There are two strategies for compiling diagrams in your project: self-compiling and using the `C4SCLI` tool.
The following code shows how to compile the diagram:

#### a) self-compiling approach:
#### Self-compiling approach:

```c#
using C4Sharp.Diagrams;
Expand Down Expand Up @@ -117,7 +170,7 @@ new PlantumlContext()
The result of the previous code is the following diagram:
![img](./docs/images/container-diagram-for-internet-banking-system-c4container.png)

### Using the C4SCLI tool:
#### Using the C4SCLI tool:

> [!TIP]\
> The `C4SCLI` can be used in DevOps pipelines, removing the need to manually compile diagrams. For this, install `C4SCLI` tool and execute de the following command:
Expand All @@ -126,7 +179,7 @@ $ c4scli build <solution path> [-o <output path>]
```

### Customizing the diagram

#### Using Themes
Themes are used to customize the diagram. The following code shows how to use the `ParadisoTheme` theme to compile the diagram:

```c#
Expand All @@ -138,6 +191,52 @@ new PlantumlContext()
The result of the previous code is the following diagram:
![img](./docs/images/container-diagram-for-internet-banking-system-v2-c4container.png)

#### Creating a custom theme

You can create a custom theme by implementing the `ITheme` interface. The following code shows how to create a custom theme:

```c#
public class DefaultTheme: IDiagramTheme
{
private const string ComponentBackground = "#85bbf0";
private const string ComponentBorder = "#78a8d9";
private const string ComponentText = "#000000";

private const string ContainerBackground = "#438dd4";
private const string ContainerBorder = "#3e82c5";
private const string ContainerText = "#FFFFFF";

private const string PersonBackground = "#0d437b";
private const string PersonBorder = "#0d437b";
private const string PersonText = "#FFFFFF";

private const string ExternalBackground = "#999999";
private const string ExternalBorder = "#8a8a8a";
private const string ExternalText = "#FFFFFF";

private const string SystemBackground = "#1a67be";
private const string SystemBorder = "#175eaa";
private const string SystemText = "#FFFFFF";

public IElementStyle? Style => new ElementStyle()
.UpdateElementStyle(ElementName.System, SystemBackground, SystemText, SystemBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 2)
.UpdateElementStyle(ElementName.ExternalSystem, ExternalBackground, ExternalText, ExternalBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 1)
.UpdateElementStyle(ElementName.Person, PersonBackground, PersonText, PersonBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 2)
.UpdateElementStyle(ElementName.Component, ComponentBackground, ComponentText, ComponentBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 2)
.UpdateElementStyle(ElementName.ExternalComponent, ExternalBackground, ExternalText, ExternalBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 1)
.UpdateElementStyle(ElementName.Container, ContainerBackground, ContainerText, ContainerBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 2)
.UpdateElementStyle(ElementName.ExternalContainer, ExternalBackground, ExternalText, ExternalBorder, false, Shape.RoundedBoxShape, BorderStyle.SolidLine, 1);

public IBoundaryStyle? BoundaryStyle => new BoundaryStyle()
.UpdateBoundaryStyle(ElementName.System, "#FFFFFF", "#000000", "#000000", false, Shape.RoundedBoxShape)
.UpdateBoundaryStyle(ElementName.Container, "#FFFFFF", "#000000", "#000000", false, Shape.RoundedBoxShape)
.UpdateBoundaryStyle(ElementName.Enterprise, "#FFFFFF", "#000000", "#000000", false, Shape.RoundedBoxShape);

public IElementTag? Tags { get; } = null;
public IRelationshipTag? RelTags { get; } = null;
}
```
#### Customizing the diagram through the SetStyle method

Using the `C4S` library, you can customize the diagram by implementing the SetStyle() method, as in the following example:

Expand All @@ -154,6 +253,8 @@ protected override IElementStyle? SetStyle()

![img](./docs/images/c4bank-deposit-area-c4container-bw.png)

### Exporting the diagram to different formats

Now, C4Sharp can compile the [Mermaid](https://github.com/mermaid-js/mermaid) markdown file. For this, you should use the function `UseDiagramMermaidBuilder()`. The following code shows how to compile these files.

```c#
Expand Down
12 changes: 6 additions & 6 deletions samples/ModelDiagrams/Structures/People.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ namespace ModelDiagrams.Structures;

public static class People
{
public static Person Customer =>
new ("customer", "Personal Banking Customer", "A customer of the bank, with personal bank accounts.", Boundary.External);
public static Person Customer => new ("customer", "Personal Banking Customer",
"A customer of the bank, with personal bank accounts.", Boundary.External);

public static Person InternalCustomer =>
new Person("internalcustomer", "Personal Banking Customer", "An customer of the bank, with personal bank accounts.");
public static Person InternalCustomer => new Person("internalcustomer", "Personal Banking Customer",
"An customer of the bank, with personal bank accounts.");

public static Person Manager =>
new ("manager", "Manager Banking Customer", "A manager of the bank, with personal bank accounts.");
public static Person Manager => new ("manager", "Manager Banking Customer",
"A manager of the bank, with personal bank accounts.");
}
2 changes: 1 addition & 1 deletion src/C4Sharp.Tools/C4Sharp.Tools.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
<RepositoryUrl>https://github.com/8T4/c4sharp</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>c4, diagrams</PackageTags>
<PackageVersion>2.3.0</PackageVersion>
<PackageVersion>3.0.0</PackageVersion>
<PackageIconUrl>https://github.com/8T4/c4sharp/blob/main/LICENSE</PackageIconUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
Expand Down
2 changes: 1 addition & 1 deletion src/C4Sharp/C4Sharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<RepositoryUrl>https://github.com/8T4/c4sharp</RepositoryUrl>
<RepositoryType>git</RepositoryType>
<PackageTags>c4, diagrams</PackageTags>
<PackageVersion>6.3.0</PackageVersion>
<PackageVersion>7.0.0</PackageVersion>
<PackageIconUrl>https://github.com/8T4/c4sharp/blob/main/LICENSE</PackageIconUrl>
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<IncludeSymbols>true</IncludeSymbols>
Expand Down
2 changes: 1 addition & 1 deletion src/C4Sharp/Diagrams/Builders/ContextDiagram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace C4Sharp.Diagrams.Builders;
public abstract class ContextDiagram: DiagramBuilder
{
protected override string Title { get; } = "Context Diagram";
protected override DiagramType DiagramType { get; } = DiagramType.Component;
protected override DiagramType DiagramType { get; } = DiagramType.Context;

protected EnterpriseBoundary Bound(string alias, string label, params Structure[] structures) =>
new(alias, label, structures);
Expand Down
23 changes: 17 additions & 6 deletions src/C4Sharp/Diagrams/Plantuml/PlantumlContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public PlantumlContext UseDiagramMermaidBuilder()
/// <param name="diagrams">C4 Diagrams</param>
/// <param name="theme"></param>
public void Export(IEnumerable<IDiagramBuilder> diagrams, IDiagramTheme? theme = null) =>
Export(diagrams.Select(d => d.Build(theme ?? new DefaultTheme())));
InternalExport(diagrams.Select(d => d.Build(theme ?? new DefaultTheme())));

/// <summary>
/// It creates a Puml file into the default directory "./c4"
Expand All @@ -97,12 +97,21 @@ public void Export(IEnumerable<IDiagramBuilder> diagrams, IDiagramTheme? theme =
/// </summary>
/// <param name="diagrams">C4 Diagrams</param>
[Obsolete("Use the method with IDiagramBuilder")]
public void Export(IEnumerable<Diagram> diagrams)
public void Export(IEnumerable<Diagram> diagrams) =>
InternalExport(diagrams);

/// <summary>
/// It creates a Puml file into the default directory "./c4"
/// If the attribute of Session GenerateDiagramImages is true
/// It generates png files of the diagram
/// </summary>
/// <param name="diagrams">C4 Diagrams</param>
private void InternalExport(IEnumerable<Diagram> diagrams)
{
var dirPath = Directory.GetCurrentDirectory();
var path = Path.Join(dirPath, C4SharpDirectory.DirectoryName);
Export(path, diagrams);
}
InternalExport(path, diagrams);
}

/// <summary>
/// It creates a Puml file into the default directory "./c4"
Expand All @@ -118,7 +127,7 @@ public void Export(IEnumerable<Diagram> diagrams)
/// <param name="theme"></param>
/// ReSharper disable once MemberCanBePrivate.Global
public void Export(string path, IEnumerable<IDiagramBuilder> diagrams, IDiagramTheme? theme = null) =>
Export(path, diagrams.Select(d => d.Build(theme)));
InternalExport(path, diagrams.Select(d => d.Build(theme)));

/// <summary>
/// It creates a Puml file into the default directory "./c4"
Expand All @@ -133,7 +142,9 @@ public void Export(string path, IEnumerable<IDiagramBuilder> diagrams, IDiagramT
/// </param>
/// ReSharper disable once MemberCanBePrivate.Global
[Obsolete("Use the method with IDiagramBuilder")]
public void Export(string path, IEnumerable<Diagram> diagrams)
public void Export(string path, IEnumerable<Diagram> diagrams) => InternalExport(path, diagrams);

private void InternalExport(string path, IEnumerable<Diagram> diagrams)
{
var enumerable = diagrams as Diagram[] ?? diagrams.ToArray();

Expand Down
3 changes: 3 additions & 0 deletions src/C4Sharp/Elements/ContainerType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ public enum ContainerType

[Description("Database")]
Database,

[Description("Pipeline")]
Pipeline,

[Description("")]
None
Expand Down
7 changes: 7 additions & 0 deletions src/C4Sharp/Elements/Containers/Pipeline.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace C4Sharp.Elements.Containers;

public record Pipeline(string Alias, string Label, string Technology, string? Description = null)
: Container(Alias, Label, ContainerType.Pipeline, Technology, Description);

public record Pipeline<T>(string Technology, string? Description = null)
: Container<T>(ContainerType.Pipeline, Technology, Description);

0 comments on commit 0755359

Please sign in to comment.