diff --git a/C4.puml b/C4.puml index 27c7b7a..58aab7e 100644 --- a/C4.puml +++ b/C4.puml @@ -36,6 +36,13 @@ skinparam LegendBorderColor transparent skinparam LegendBackgroundColor transparent skinparam LegendFontColor $LEGEND_FONT_COLOR +skinparam shadowing<> false +' #00000000 is transparent +skinparam rectangle<> { + backgroundcolor #00000000 + bordercolor #00000000 +} + skinparam rectangle { StereotypeFontSize 12 shadowing false @@ -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 @@ -497,6 +504,25 @@ SetPropertyHeader("Property","Value") ' Layout ' ################################## +!procedure $getHideStereotype($hideStereotype) +!if ($hideStereotype=="true") +hide stereotype +!endif +!endprocedure + +!procedure $getLegendTable() +<#00000000,#00000000>|**Legend** | +$showActiveLegendEntries($tagDefaultLegend) +$showActiveLegendEntries($tagCustomLegend) +!endprocedure + +!procedure $getLegendArea($areaAlias, $hideStereotype) +$getHideStereotype($hideStereotype) +rectangle $areaAlias<> [ +$getLegendTable() +] +!endprocedure + !procedure HIDE_STEREOTYPE() hide stereotype !endprocedure @@ -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 -|**Legend** | -$showActiveLegendEntries($tagDefaultLegend) -$showActiveLegendEntries($tagCustomLegend) +$getLegendTable() endlegend !endprocedure @@ -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 ' ################################## @@ -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 @@ -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 diff --git a/LayoutOptions.md b/LayoutOptions.md index a472455..4dbc3b6 100644 --- a/LayoutOptions.md +++ b/LayoutOptions.md @@ -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. diff --git a/README.md b/README.md index 2f2dae4..da53dc1 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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) diff --git a/percy/TestFloatingLegend.puml b/percy/TestFloatingLegend.puml new file mode 100644 index 0000000..025cace --- /dev/null +++ b/percy/TestFloatingLegend.puml @@ -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