Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use default bgColor and fontColor for new element tags #154

Closed
dannief opened this issue Jun 5, 2021 · 7 comments · Fixed by #173
Closed

Use default bgColor and fontColor for new element tags #154

dannief opened this issue Jun 5, 2021 · 7 comments · Fixed by #173
Milestone

Comments

@dannief
Copy link

dannief commented Jun 5, 2021

In the diagram below, when new elements or rel tags are defined, if $fontColor or $bgColor are not specified (for element tags for example), then the generated legend shows texts: (no text) and (no back color). But since the element or relation uses the default colors, if not defined in the procedure, I think we should use the same colors in the legend. I find I keep setting the colors back to default colors, just so that (no text) and (no back color) are not displayed in the legend.

'  code removed for brevity ...

AddElementTag("v1.0", $borderColor="#d73027")
AddElementTag("v1.1", $fontColor="#d73027")
AddElementTag("backup", $fontColor="orange")

AddRelTag("backup", $textColor="orange", $lineColor="orange")

'  code removed for brevity ...

Example C4 Model

@kirchsth
Copy link
Contributor

kirchsth commented Jun 5, 2021

But since the element or relation uses the default colors, if not defined in the procedure, I think we should use the same colors in the legend

Which color should be used with v1.1? The "dark blue" person or the "blue" container? I think there is no logic rule which can be used. Therefore I introduced the undefined colors. You can overwrite it in your diagram

!global $LEGEND_UNDEFINED_BG_COLOR = "#D5CFEE"
!global $LEGEND_UNDEFINED_FONT_COLOR = "#8B77E4"

The legend texts are constants and can be changed too like below

!global $LEGEND_SHADOW_TEXT = "(shadow) "
!global $LEGEND_NO_SHADOW_TEXT = "(no shadow) "
!global $LEGEND_NO_FONT_BG_TEXT = "(no text, no back color) "
!global $LEGEND_NO_FONT_TEXT = "(no text color) "
!global $LEGEND_NO_BG_TEXT = "(no back color) "
!global $LEGEND_NO_LINE_TEXT = "(no line color) "

In #150 I implemented a better "undefined/default" color handling, maybe you want to check it too.
(#150 changes the color constant names!)

BR Helmut

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

!global $LEGEND_UNDEFINED_BG_COLOR = "green"
!global $LEGEND_UNDEFINED_FONT_COLOR = "lightgreen"

!global $LEGEND_NO_FONT_BG_TEXT = "[no font/background]"
!global $LEGEND_NO_BG_TEXT = ""

AddElementTag("v1.0", $borderColor="#d73027")
AddElementTag("v1.1", $fontColor="#d73027")
AddElementTag("backup", $fontColor="orange")

AddRelTag("backup", $textColor="orange", $lineColor="orange")

Person(user, "Customer", "People that need products")
Person(admin, "Administrator", "People that administrates the products via the new v1.1 components", $tags="v1.1")
Container(spa, "SPA", "angular", "The main interface that the customer interacts with via v1.0", $tags="v1.0")
Container(spaAdmin, "Admin SPA", "angular", "The administrator interface that the customer interacts with via new v1.1", $tags="v1.1")
Container(api, "API", "java", "Handles all business logic (incl. new v1.1 extensions)", $tags="v1.0+v1.1")
ContainerDb(db, "Database", "Microsoft SQL", "Holds product, order and invoice information")
Container(archive, "Archive", "Audit logging", "Stores 5 years", $tags="backup")

Rel(user, spa, "Uses", "https")
Rel(spa, api, "Uses", "https")
Rel_R(api, db, "Reads/Writes")
Rel(admin, spaAdmin, "Uses", "https")
Rel(spaAdmin, api, "Uses", "https")
Rel_L(api, archive, "Writes", "messages", $tags="backup")

SHOW_LEGEND()
@enduml

@dannief
Copy link
Author

dannief commented Jun 9, 2021

@kirchsth I don't think this implementation would be useful to me. This is because, it doesn't adhere to how I think the legend should work and doesn't follow the legend entry patterns for default items like person and container. What I mean is, the person entry in the legend has the same font color and background color as the actual element and so you are easily able to correlate the legend entry to the element type in the diagram. However, for the new tag, v1.1, for example, the legend entry has a background color of green, while the tag is applied to elements with background colors dark blue and light blue respectively. I think you can't easily correlate the legend entry with the actual elements in those cases, which makes the legend not so useful

In your example above, I think there should be 2 different v1.0 tags, one for the container and the other for the person. In that case the 2 legend entries would have a font color and background color that matches the elements they are trying to describe. See below:

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

AddElementTag("v1.0", $borderColor="#d73027", $bgColor=$CONTAINER_BG_COLOR, $fontColor=$ELEMENT_FONT_COLOR)
AddElementTag("container_v1.1", $fontColor="#d73027", $bgColor=$CONTAINER_BG_COLOR)
AddElementTag("person_v1.1", $fontColor="#d73027", $bgColor=$PERSON_BG_COLOR)
AddElementTag("backup", $fontColor="orange", $bgColor=$CONTAINER_BG_COLOR)

AddRelTag("backup", $textColor="orange", $lineColor="orange")
AddRelTag("db_read_writes", $textColor="blue", $lineColor=$ARROW_COLOR)

Person(user, "Customer", "People that need products")
Person(admin, "Administrator", "People that administrates the products via the new v1.1 components", $tags="person_v1.1")
Container(spa, "SPA", "angular", "The main interface that the customer interacts with via v1.0", $tags="v1.0")
Container(spaAdmin, "Admin SPA", "angular", "The administrator interface that the customer interacts with via new v1.1", $tags="container_v1.1")
Container(api, "API", "java", "Handles all business logic (incl. new v1.1 extensions)", $tags="v1.0+container_v1.1")
ContainerDb(db, "Database", "Microsoft SQL", "Holds product, order and invoice information")
Container(archive, "Archive", "Audit logging", "Stores 5 years", $tags="backup")

Rel(user, spa, "Uses", "https")
Rel(spa, api, "Uses", "https")
Rel_R(api, db, "Reads/Writes", $tags="db_read_writes")
Rel(admin, spaAdmin, "Uses", "https")
Rel(spaAdmin, api, "Uses", "https")
Rel_L(api, archive, "Writes", "messages", $tags="backup")

SHOW_LEGEND()
@enduml

image

The above code and resultant image shows how I typically define new tags to ensure correct legend entries.

So I suppose what I am really looking for then, are specialized AddElementTag and AddRelTag procedures that will set default styles based on the element the tag is being applied to. Perhaps as below:

AddPersonTag()
AddSystemTag()
AddContainerTag()
AddComponentTag()

I think we can currently set defaults for AddRelTag without introducing a new procedure?

@kirchsth
Copy link
Contributor

kirchsth commented Jun 9, 2021

you can change the default person,... and relations style with calls like

UpdateElementStyle("person", ....)
UpdateRelStyle(....) 

Is this what you want? (source of the image is in Read.me)

BR Helmut

@dannief
Copy link
Author

dannief commented Jun 9, 2021

@kirchsth No, I am not trying to update the default element and relation styles as that will change the style of all the element and relation types specified in UpdateElementStyle and UpdateRelStyle respectively. I am referring to creating tags that will affect just the elements and relations they are applied to.

The issue is what happens when we use the procedures to add a tag to an element or relation and we do not specify all the arguments. What I am proposing is how the library should set the unspecified arguments for display in the legend.

If I have 2 containers, where I would like to add a tag to one of them, then I use the AddElementTag procedure. However, I only wish to change the fontColor of the default container styling. I achieve this as expected by calling the AddElementTag procedure as below. And this produces a tagged container that will have only the font color changed, while the background color and borders still have the default container styles. However, the legend, in my opinion is incorrect. The legend entry for tagged has background color of pink and does not show the rectangle denoting the border color of the element. It is not obvious what that legend entry relates to.

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

AddElementTag(tagged, $fontColor=red)

Container(default, Container 1, tech)
Container(tagged, Container 2, tech, $tags="tagged")

SHOW_LEGEND()
@enduml

image

In my opinion, the legend should be displayed as below.
image

The unspecified AddElementTag arguments should not use random colors that results in the legend entry not directly correlating to the displayed element i.e. not having the same bgColor, fontColor and borderColor as the element.

But since the current AddElementTag and AddRelTag procedures cannot know the element to which the tag will applied, in order to achieve the legend entry as in the 2nd image, I typically specify the default style values manually like so:

AddElementTag(tagged, $fontColor=red, $bgColor=$CONTAINER_BG_COLOR, $borderColor=$CONTAINER_BORDER_COLOR)

So I will then only apply that tag to a container element.

In order that users do not have to always specify all the argument values to generate a proper legend, I am proposing that new procedures be created e.g.

!procedure AddContainerTag($tagStereo, $bgColor=$CONTAINER_BG_COLOR, $fontColor=$ELEMENT_FONT_COLOR, $borderColor=$CONTAINER_BORDER_COLOR, $shadowing="false")
  AddElementTag($tagStereo, $bgColor, $fontColor, $borderColor, $shadowing)
!endprocedure

!procedure AddPersonTag($tagStereo, $bgColor=$PERSON_BG_COLOR, $fontColor=$ELEMENT_FONT_COLOR, $borderColor=$PERSON_BORDER_COLOR, $shadowing="false")
  AddElementTag($tagStereo, $bgColor, $fontColor, $borderColor, $shadowing)
!endprocedure

Or alternatively we can extend UpdateElementStyle and UpdateRelStyle to accept a stereo name so that it will only update the style of elements with the given tag e.g.

' Only update default styling for given `elementName` tagged with `tag` value
UpdateElementStyle(elementName, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?tag)

' example
UpdateElementStyle("container", $fontColor="red", $tag="tagged")

Or even better

AddElementTag($tagStereo, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?elementName)

' Style will only be applied to elements with stereo <<tagged>> AND <<container>>. 
' Since we know we are applying the style to a container, we can use the container bgColor and borderColor if not specified
AddElementTag("tagged", $fontColor="red", $elementName="container")

This pattern should apply also to the current functionality of UpdateElementStyle.

Given the below code

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

' AddElementTag(tagged, $fontColor=red)
UpdateElementStyle("container", $fontColor=red)

Container(default, Container 1, tech)
Container(tagged, Container 2, tech, $tags="tagged")

SHOW_LEGEND()
@enduml

Since I didn't specify a bgColor, I get the following legend with a pink background and a text specifying "no back color"
image

I would have expected the following instead. (Assumed that since bgColor is not a required argument, the bgColor of both the legend and element specified (container) would use the default color of $CONTAINER_BG_COLOR
image

Hope this is clearer

@kirchsth
Copy link
Contributor

I think I understand your wish, following source

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

AddElementTag("tagged", $fontColor=red)

Container(c1, Container 1, tech)
Container(cTagged, Container 2, tech, $tags="tagged")
Person(p1, Person 1)
Person(pTagged, Person 2, $tags="tagged")

SHOW_LEGEND()
@enduml

should be displayed like

But PlantUML offers only few preprocessor calls (details). You could try to extend SHOW_LEGEND() with missing functionanlity and create a PR (please don't forget the combination of multiple tags, ....).

BR Helmut

PS.: source of the diagram based on the current implementation

@startuml
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml

AddElementTag("tagged", $fontColor=red)
AddElementTag("tagged container", $fontColor=red, $bgColor = $CONTAINER_BG_COLOR, $borderColor = $CONTAINER_BORDER_COLOR)
AddElementTag("tagged person", $fontColor=red, $bgColor = $PERSON_BG_COLOR, $borderColor = $PERSON_BORDER_COLOR)

Container(c1, Container 1, tech)
Container(cTagged, Container 2, tech, $tags="tagged container")
Person(p1, Person 1)
Person(pTagged, Person 2, $tags="tagged person")

SHOW_LEGEND()
@enduml

@kirchsth
Copy link
Contributor

@dannief in #157 I showed a soution to hide default tags and uses only explicit defined tags (which could represent a tag combination too) maybe this is an approach for you

@kirchsth
Copy link
Contributor

kirchsth commented Aug 8, 2021

Hi @dannief,

with #173 I added Element specific tag defintions with element specific default colors like

  • AddPersonTag(tagStereo, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?legendText, ?legendSprite)
  • AddExternalPersonTag(tagStereo, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?legendText, ?legendSprite)
  • AddSystemTag(tagStereo, ?bgColor, ?fontColor, ?borderColor, ?shadowing, ?shape, ?sprite, ?legendText, ?legendSprite)
  • ...

that repeated color defintions can be avoided like below

@startuml
!include https://raw.githubusercontent.com/kirchsth/C4-PlantUML/extended/C4_Container.puml

' AddElementTag("tagged", $fontColor=red)
AddContainerTag("tagged container", $fontColor=red)
AddPersonTag("tagged person", $fontColor=red)

Container(c1, Container 1, tech)
Container(cTagged, Container 2, tech, $tags="tagged container")
Person(p1, Person 1)
Person(pTagged, Person 2, $tags="tagged person")

SHOW_LEGEND()
@enduml

Maybe this helps.
BR Helmut

@Potherca Potherca added this to the v2.4.0 milestone Sep 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

Successfully merging a pull request may close this issue.

3 participants