Skip to content

Commit

Permalink
Merge pull request #143 from kirchsth/feature/141_incl_SHOW_LEGEND_LEFT
Browse files Browse the repository at this point in the history
 #134: Legend fill whitespace with SHOW_FLOATING_LEGEND() and Lay_Distance()
  • Loading branch information
Potherca authored Jul 4, 2021
2 parents 8f4fa65 + fb5c125 commit 24d9735
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 12 deletions.
59 changes: 52 additions & 7 deletions C4.puml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ skinparam LegendBorderColor transparent
skinparam LegendBackgroundColor transparent
skinparam LegendFontColor $LEGEND_FONT_COLOR

skinparam shadowing<<legendArea>> false
' #00000000 is transparent
skinparam rectangle<<legendArea>> {
backgroundcolor #00000000
bordercolor #00000000
}

skinparam rectangle {
StereotypeFontSize 12
shadowing false
Expand Down Expand Up @@ -63,7 +70,7 @@ skinparam actor {
style awesome
}

' Some boundary skinparam have to be set a package skinparams too (PlantUML uses internal packages)
' Some boundary skinparams have to be set as package skinparams too (PlantUML uses internal packages)
skinparam package {
StereotypeFontSize 6
StereotypeFontColor $BOUNDARY_BG_COLOR
Expand Down Expand Up @@ -497,6 +504,25 @@ SetPropertyHeader("Property","Value")
' Layout
' ##################################

!procedure $getHideStereotype($hideStereotype)
!if ($hideStereotype=="true")
hide stereotype
!endif
!endprocedure

!procedure $getLegendTable()
<#00000000,#00000000>|<color:$LEGEND_TITLE_COLOR>**Legend**</color> |
$showActiveLegendEntries($tagDefaultLegend)
$showActiveLegendEntries($tagCustomLegend)
!endprocedure

!procedure $getLegendArea($areaAlias, $hideStereotype)
$getHideStereotype($hideStereotype)
rectangle $areaAlias<<legendArea>> [
$getLegendTable()
]
!endprocedure

!procedure HIDE_STEREOTYPE()
hide stereotype
!endprocedure
Expand All @@ -518,13 +544,9 @@ left to right direction

' has to be last call in diagram
!unquoted procedure SHOW_LEGEND($hideStereotype="true")
!if ($hideStereotype=="true")
hide stereotype
!endif
$getHideStereotype($hideStereotype)
legend right
|<color:$LEGEND_TITLE_COLOR>**Legend**</color> |
$showActiveLegendEntries($tagDefaultLegend)
$showActiveLegendEntries($tagCustomLegend)
$getLegendTable()
endlegend
!endprocedure

Expand All @@ -533,6 +555,18 @@ endlegend
SHOW_LEGEND($hideStereotype)
!endprocedure

' legend is reserved and cannot be uses as alias of SHOW_FLOATING_LEGEND() therefore
' LEGEND() is introduced. It returns the default name of the floating alias "floating_legend_alias"
' and can be used in the Lay_Distance() calls
!function LEGEND()
!return "floating_legend_alias"
!endfunction

' enables that legend can be located in drawing area of the diagram. It has to be last call in diagram followed by Lay_Distance()
!unquoted procedure SHOW_FLOATING_LEGEND($alias=LEGEND(), $hideStereotype="true")
$getLegendArea($alias, $hideStereotype)
!endprocedure

' Boundaries
' ##################################

Expand Down Expand Up @@ -668,6 +702,10 @@ $getRel("<<-RIGHT->>", $from, $to, $label, $techn, $descr, $sprite, $tags, $link
' Layout Helpers
' ##################################

!function $getHiddenLine($distance)
!return '-[hidden]' + %substr('------------', 0, %intval($distance) + 1)
!endfunction

!unquoted procedure Lay_D($from, $to)
$from -[hidden]D- $to
!endprocedure
Expand All @@ -680,3 +718,10 @@ $from -[hidden]R- $to
!unquoted procedure Lay_L($from, $to)
$from -[hidden]L- $to
!endprocedure

' PlantUML bug: lines which does "not match" with the orientation/direction of the diagram
' uses the same length therefore the method offers no direction at all.
' If a direction is required the Lay_...() methods can be used
!unquoted procedure Lay_Distance($from, $to, $distance="0")
$from $getHiddenLine($distance) $to
!endprocedure
52 changes: 52 additions & 0 deletions LayoutOptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,58 @@ SHOW_LEGEND()

![SHOW_LEGEND Sample](https://www.plantuml.com/plantuml/png/JL5Dgzf05DtFhxYr2oDeWgMhhfgceWkreObr6IR9RHsOZs7cXY3b_VTtWpurcqlEn-4Svdia6MWm6ghThtEptsmtnvzGIUCrYa_ATdhe4Iv4FdxBiY37z9-Yoz0E4KFdBA6bj7CcyrhQAMOLgTUgpOglgtA2JeTzPcGa30mr1JkaiXXIpreXIWpHsKJsHjabpFBfgaX1aWkpXQYkR3JD3pVONePhqgsNCBzrco_Wlm3-7f79Y6qZlUUSCxQGUwzL9qavEsEe-Bo4l2hJuwPcIq3uagxXyAUOk5nhDqQO9aKW1xp7IvQOGPFo6g4U5H4686LGAukHkxtTsoLq8pddBcDI_4RziUfPwnJPoNTNrsN5gadqO9ynMwJ8lpYTly6PLujuUQLa8Tu1 "SHOW_LEGEND Sample")

## SHOW_FLOATING_LEGEND(?alias, ?hideStereotype) and LEGEND()

`LAYOUT_WITH_LEGEND()` and SHOW_LEGEND(?hideStereotype)` adds the legend at the bottom right of the picture like below and additional whitespace is created.

```csharp
@startuml Layout With Whitespace Sample
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Person(a, "Person A")
Container(b, "Container B", "techn")
System(c, "System C")
Container(d, "Container D", "techn")
Container_Ext(e, "Ext. Container E", "techn")

Rel_R(a, b, "calls")
Rel_D(b, c, "uses")
Rel_D(c, d, "uses")
Rel_R(d, e, "updates")

SHOW_LEGEND()
@enduml
```

![Layout With Whitespace Sample](https://www.plantuml.com/plantuml/png/LSwnReCm40RWtK_XCZbI0qkdJca1jGDjew2A4HdxL91iOzbdjNdx7eb4meJlk_y_SOWe0oPhU2FFSqBUJJZoRfmGefSAU2kjDy0U9gTCqi17H1-VYoB8t_o7icb84OAQ7OB3NCssy4QwvU8-eZRJK9HF--D2tnzDOML424HzIGqvEGYvfonZHmXnTa8-ykpwv2_PZgqfCT1YdVXhHYE26Xs5sZCTjK8HNP-yt5JrfbhTLrVkwpyKG1lwvloMhk_Jx0IcFot_E90gQKmaNR0I98emHRWPWTuObGbWCQybNfYrxrzTtzHlzMSbTkm0JYTh_W40 "Layout With Whitespace Sample")

Therefore a floating legend can be added via SHOW_FLOATING_LEGEND(), positioned with Lay_Distance() and existing whitespace is reused like below.

- `SHOW_FLOATING_LEGEND(?alias, ?hideStereotype): shows the legend in the drawing area
- `LEGEND()`: is the default alias of the created floating legend and can be used in Lay_Distance() call

```csharp
@startuml Compact Legend Layout Sample
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
Person(a, "Person A")
Container(b, "Container B", "techn")
System(c, "System C")
Container(d, "Container D", "techn")
Container_Ext(e, "Ext. Container E", "techn")

Rel_R(a, b, "calls")
Rel_D(b, c, "uses")
Rel_D(c, d, "uses")
Rel_R(d, e, "updates")

SHOW_FLOATING_LEGEND()
Lay_Distance(LEGEND(), e, 1)
@enduml
```

![Compact Legend Layout Sample](https://www.plantuml.com/plantuml/png/RP7VQ-em5CVVyrUavS9juTwMmPu60vtjtA1JqOqzXfWURLXC9Jbb-j_lr6gri9Ss-Nn_d3OPUPGEcvrXWRRAD2Nm2d7l7zBKoUzagx5greq7fsgBO35HzIxzqavL7gjqSlz_OQJ5ZxSYXGFf9PG4nOJCKbjmoRwjPcm1pjSsalzus2tvE8nPRulM9FGx_XJI5a5LbaoheqVOHOfGj-IJGRGSHBFRQ8z5Vi08IA5tmg_k_DRDbc34ilt6DL4bZV54MvX5H1H1EeWh8r0EsJ8Y02tRbn9Fc0MRnYhKzCT5FirdMHIpm04spl9mOsg9scw5WItOCcG1FIz-jdgPVuhdOZv-VvrDnJbzAObP8OyYqtHzLa6FJ-FlQ2pxouC_7UMFFEm62Eb0XYJzMdssnwGFki_yKZsY8hhK7m00 "Compact Legend Layout Sample")

## LAYOUT_AS_SKETCH()

C4-PlantUML can be especially helpful during up-front design sessions.
Expand Down
46 changes: 41 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,10 +280,10 @@ Rel_D(user, user1, "requests", "async message", "if sprite starts with &, it def
In rare cases, you can force the layout of objects which have no relationships by using:

* `Lay_U`
* `Lay_D`
* `Lay_L`
* `Lay_R`
* `Lay_U(from, to)`
* `Lay_D(from, to)`
* `Lay_L(from, to)`
* `Lay_R(from, to)`

In following sample a person uses different systems, and group of persons which have no relations

Expand Down Expand Up @@ -318,12 +318,48 @@ Rel_L(x, s4, "uses")

![Relation versus Layout](https://www.plantuml.com/plantuml/png/LSt1QeD04CRnkq-HvgJGA55FFQLLeGLBHIEq9rbrQ8HrbTrPshnzPmn5Svl_3_RRaq6XqOxIUHXK9sqFkmlYR9w2G8iV_tl0Yssj0TrD2a6XtqrZC4kX-Ct1O2-7DaZYGy5Kl-V1A0o29ceIUY461TgVUV_rBSsQwfoLsSVvgyXSpt4Aq6PIhdZSxP_ttd-sb2zhTfJ9cZrbkYPGPfHEBgvDpLEjjzmbtztjJldkRtVEDwoV_zB09mrKLuCmkkP8NHqt43A46uWOeWt43361Ku9iQfvSPgm1GyfOBXZUOxfWT8_vWl6A9r2z7UKV "Relation versus Layout")
(In combination with [SHOW_FLOATING_LEGEND()](LayoutOptions.md#show_floating_legend)) a greater distance between an element and the
e.g. floating legend could be required that all e.g. corners of the drawing area can be reached.

* `Lay_Distance(from, to, ?distance)`: Sets the distance between `from` and `to` with down alignment (Lay_Distance(from,to,0) equals Lay_D(from, to)). The default alias of the floating legend is LEGEND().

In following sample the floating legend should be in the left bottom corner of the drawing are.
(The normal SHOW_LEGEND() call requires no extra Lay_Distance() call and the legend is automatically drawn below the diagram on the right side)

```
@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!define FONTAWESOME https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/font-awesome-5
!include DEVICONS/angular.puml
!include DEVICONS/java.puml
!include DEVICONS/msql_server.puml
!include FONTAWESOME/users.puml

Person(user, "Customer", "People that need products", $sprite="users")
Container(spa, "SPA", "angular", "The main interface that the customer interacts with", $sprite="angular")
Container(api, "API", "java", "Handles all business logic", $sprite="java")
ContainerDb(db, "Database", "Microsoft SQL", "Holds product, order and invoice information", $sprite="msql_server")

Rel(user, spa, "Uses")
Rel(spa, api, "Uses")
Rel_R(api, db, "Reads/Writes")

SHOW_FLOATING_LEGEND()
Lay_Distance(LEGEND(), db, 1)
@enduml
```

![db below legend, 1 unit distance](https://www.plantuml.com/plantuml/png/hL5DZzem4BtdLtXH3o0jH5NRIwLAYu3THUA30bkEqH0FuCgnKyy4r7_VCIIxKQjAFVGKvptFUtvl7eWXS5NOvCwut5OQrOcvfCzf6k0oE1e-LVkACEJUCJeUvBv8ImikplI9jJNxTFInluhGotoM5a2CGQ1i91DW78P16VMJEuq7-LNZoRVfQBdO_8CHLoNeyE7Dq0ZRFyYDFfN1C5BZf_4SENfrULmkjiFTPBESJ_whqHM32v8liF-fQUqjLGhkM5ceG_z9VuSp_8qhw8VD2CCPVnjlfqdZswdkT2L7xxeHkbUTKKNi2mmTEQ_GbnOLdu2LGzIg35vNEPEGxswPldIkKfrUyhggBfKWmvlLC6hKKU9nUq9Lo1Lb76CuG5vBi-1vRNlZG3pKHLfk6pLARIieZGWFLzEe7sk9tsTmsY8fi5R9bkGYaRB-QFAsNBpTrXhlktelqsDWs0DXL9gRF7Zo1rQRhxEhjBUQcXhkbGyQWn8xUVRPcnpbU_2X03RUjSrQMn7FP8ssxllMrGiX2HxXAn1ZjT5iVKjwVU0QGLEwYyAHJZRFortsE5iEjzF5KpQRF4qMusulcS7FR6o8mUNORT2RnFjUye1Eo_P_0G00 "db below legend, 1 unit distance")
## Layout Options

C4-PlantUML also comes with some layout options to make it easy and reusable to create nice and useful diagrams:

* [LAYOUT_TOP_DOWN() or LAYOUT_LEFT_RIGHT()](LayoutOptions.md#layout_top_down-or-layout_left_right)
* [LAYOUT_WITH_LEGEND() or SHOW_LEGEND(?hideStereotype)](LayoutOptions.md#layout_with_legend-or-SHOW_LEGEND)
* [LAYOUT_WITH_LEGEND() or SHOW_LEGEND(?hideStereotype)](LayoutOptions.md#layout_with_legend-or-show_legend)
* [SHOW_LEGEND_UP(alias, ?hideStereotype), SHOW_LEGEND_DOWN(...), SHOW_LEGEND_LEFT(...), SHOW_LEGEND_RIGHT(...)](LayoutOptions.md#show_legend_up-show_legend_down-show_legend_left-show_legend_right)
* [LAYOUT_AS_SKETCH()](LayoutOptions.md#layout_as_sketch)
* [HIDE_STEREOTYPE()](LayoutOptions.md#hide_stereotype)

Expand Down
22 changes: 22 additions & 0 deletions percy/TestFloatingLegend.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@startuml
' convert it with additional command line argument -DRELATIVE_INCLUDE="." to use locally
!if %variable_exists("RELATIVE_INCLUDE")
!include ./../C4_Container.puml
!else
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
!endif

Person(a, "Person A")
Container(b, "Container B", "techn")
System(c, "System C")
Container(d, "Container D", "techn")
Container_Ext(e, "Ext. Container E", "techn")

Rel_R(a, b, "calls")
Rel_D(b, c, "uses")
Rel_D(c, d, "uses")
Rel_R(d, e, "updates")

SHOW_FLOATING_LEGEND()
Lay_Distance(LEGEND(), e, 1)
@enduml

0 comments on commit 24d9735

Please sign in to comment.