Stylesheets in PlantUML?

+5 votes
asked Dec 19, 2013 in Wanted features by rmric (2,140 points)

Is it possible to create its own stylesheet in PlantUML code?

I've looked at skinparam, but haven't completely find a way (v7988).
I'm not asking for CSS smiley, just something like the following.

Let's say in a component diagram, I have 2 kinds of component, for example a static library and a shared library.
I like PlantUML because it's a WYSIWYM processor. So when I create a library component, I only want to flag it as static_lib or shared_lib, and set the color, font, etc. later, once. So later on, a stylesheet (skinparam?) can be applied to every component flagged.

It looks like there's an under advertised feature with stereotyped skinparam, mentioned in the component's skinparam example and SkinnedStereotypes. (a reference in skinparam.html would be great). Nothing found in reference guide v5737.

The following works as expected:

@startuml
[AA] <<static lib>>
[BB] <<shared lib>>
[CC] <<static lib>>
[Leave me alone] << other lib >>

skinparam component {
    backgroundColor<<static lib>> Red
    backgroundColor<<shared lib>> Green
}
@enduml

 

However, it looks like I can't skinparam a package/node/folder/frame/cloud/database/interface. What about actor/boundary/control/entity ?
They are not listed in skinparam.html either. Is it all a matter of introducing that bunch of params?
packageBackgroundColor, packageFontName, etc.

Regarding package, won't I run into trouble with predefined stereotypes <<Node>>, <<Rect>>, <<Folder>>, <<Frame>>, <<Cloud>>, <<Database>> ? ie. can I specify a stereotype <<Frame>><<static_lib>> ? maybe better use the frame keyword?

One last wish: could it be possible to hide the stereotype name of a component/package/etc., through a skin ? The stereotype would serve as a "style name" in that case.

hide component <<static lib>> stereotype

skinparam component {
    hide <<static lib>> stereotype
}

 

Rem: "factorizing" the SkinnedStereotype would make sense, but I can live without it.

skinparam component<<static lib>> {
    hide stereotype
    backgroundColor Red
}

Looks like pre-xmas time, with a lot in the wishlist, but who knows..

Thanks

3 Answers

0 votes
answered Dec 20, 2013 by plantuml (294,660 points)
Very interesting contribution!

We will read it more carefully, but extending skinparam should be easy.

We will post news here when this will be ready.

Regards,
+1 vote
answered Jan 2, 2014 by plantuml (294,660 points)

Hello,

With version 7989, you can use:

@startuml
[AA] <<static lib>>
[BB] <<shared lib>>
[CC] <<static lib>>

node node1
node node2 <<shared node>>
database Production

skinparam component {
    backgroundColor<<static lib>> DarkKhaki
    backgroundColor<<shared lib>> Green
}

skinparam node {
    borderColor Green
    backgroundColor Yellow
    backgroundColor<<shared node>> Magenta
}
skinparam databaseBackgroundColor Aqua

@enduml


You can use package/node/folder/frame/cloud/database/...
Only border and background color are modifiable, right now.

Next step will be to allow font change. Since this will mean many (too many?) params, the documentation itself should (probably) be changed.
Then the ability to hide stereotypes.

Feedback welcome!
 

commented Jan 8, 2014 by rmric (2,140 points)
Many thanks for v7989. The next feature would be the ability to hide stereotypes.

In v7989, stereotyping+skinparm looks fine for package,node,folder,frame,cloud,database,actor,boundary,control,entity.

However, stereotyped 'sequenceParticipant' does not work.

@startuml
skinparam sequenceParticipant {
     backgroundColor Yellow
     backgroundColor<<st>> LightBlue
}

participant AA<<st>>
participant BB

AA -> BB
@enduml

'actor' does not work at all, no color is assigned (stereotyped or not).

'interface' does not work (stereotyped or not). However, there's a side-effect: the _component_ stereotyped skinparam is bleeding on the interface's. The following snippet yields an interface II1 in *Blue*, circled with Red. interface II2 is yellow circled with Red.

@startuml
skinparam component {
  backgroundColor<<st>> Blue
}

skinparam interface {
  backgroundColor Brown
  backgroundColor<<st>> Green
}
interface II1 <<st>>
interface II2
@enduml

BTW, an empty 'package' does not get any skinparam applied.

I know it may sound kind of weird, but could it be possible to stereotype an arrow?
Indeed, in a component/sequence/.. diagram, you may want to specify the meaning of an arrow (eg. function call, IPC, etc.) in order to apply  a style sheet.

@startuml
participant A
participant B

skinparam participant {
  ArrowColor Brown
  ArrowColor<<st>> Green
}
A -<<st>> B

In that logic, it would be nice to have a new skinparam for the arrow style, either the syntax token (->, =>, ->>, ..), or the explicit name (plain, double, thin, dotted, ..):

skinparam participant {
  ArrowStyle ->
  ArrowStyle<<st>> -->>
}

BTW, the => syntax (double) is missing from the doc at http://plantuml.sourceforge.net/sequence.html#Arrow . PlantUML is so great it has it, but newcomers might be happy to see it in the documentation :-)
commented Jan 14, 2014 by plantuml (294,660 points)
Some news, in the current beta:
https://dl.dropboxusercontent.com/u/13064071/plantuml.jar

sequenceParticipant are fixed, actor also work.
Interfaces are somehow fixed (in component diagram).
And empty package do have skinparam

@startuml
skinparam sequenceParticipant {
     backgroundColor Yellow
     backgroundColor<<st>> LightBlue
}
participant AA<<st>>
participant BB
AA -> BB
@enduml

Let's talk about stereotype for arrows in another thread (to be created).
Hide stereotype are still to be implemented.

Regards,
commented Jan 15, 2014 by rmric (2,140 points)
Thanks for the beta.
I confirm the fix about sequenceParticipant and actor.
However skinparam'd actor is not working in component diagram. The boundary/entity/control are fine though, in sequence and component.
The interface is fine in component diagrams for now.

skinparam'd package somewhat works, but still not OK when empty (CC and DD):

@startuml
skinparam package {
    backgroundColor Yellow
    backgroundColor<<st>> LightBlue
}
package AA <<st>> {
  [ZZ]
}
package BB {
  [XX]
}
package CC {
}
package DD
@enduml

All the other grouping components work, but ONLY when empty. Actually, as soon as they're followed by { } empty or not, they stop working, i.e. "node DD" works, but "node CC { \n }" doesn't. The issue can be reproduced by replacing package by node in previous full example.

BTW, have you noticed that package without { } is "swallowing" the drawing coming up next ? In the below example, EE would be rendered inside DD, which is confusing, while it should appear on its side :
@startuml
package DD
package EE
@enduml

The other groupings (node, folder,..) are unaffected and render as expected.

I'll open a new thread to talk about stereotyped arrows.

Regards
commented Jan 16, 2014 by plantuml (294,660 points)
Packages/other grouping should work better with the following beta:
https://dl.dropboxusercontent.com/u/13064071/plantuml.jar

Thanks for your tests & feedback
commented Jan 17, 2014 by rmric (2,140 points)
edited Jan 17, 2014 by rmric
Indeed, the beta works a lot better. Thanks!
artefact and storage have been tested too, they are fine.
For completeness, here are the remaining issues:

1) 'actor' still get no skinparam (stereotyped or not) in *component* diagrams (it's fine in sequence diagram).

@startuml
[XX]
skinparam actor {
    backgroundColor Yellow
    backgroundColor<<st>> LightBlue
}
actor AA <<st>>
actor BB
@enduml

1b) 'agent' gets no skinparam (stereotyped or not) in *component* diagrams, but is this element allowed in that diagram?

2) I also checked 'rect' in component diagram. It does honor the skinparam (stereotyped or not), but with the skinparam keyword Rectangle instead of rect. Besides, it looks like rect does no allow to group components, ie.   rect blah { [XXX]   }  is rejected.

3) A one line 'package' is still "swallowing" the following line. The EE component should not be inside DD, but aside in this example :
@startuml
package DD
[EE]
@enduml

Regards

EDIT: rect's skinparam as Rectangle, agent not working too, artefact&storage are fine.
commented Jan 19, 2014 by plantuml (294,660 points)
Thanks again for your tests.
We have removed "rect", as it was a duplicate for "rectangle".
agent/actor are working fine now, as your last example.

Just download the last beta:
https://dl.dropboxusercontent.com/u/13064071/plantuml.jar

Feedback still welcome!
commented Jan 20, 2014 by rmric (2,140 points)
Everything's fine, this is great. Many thanks!

Now just some remarks. An agent has the same look as a rectangle, and a folder has the same look as a package. I don't know what the UML standard recommends.

There's two caveats to know, not necessary to be fixed, as long as they are documented. BTW, is the plantumldoc tree also available as a svn/git repo somewhere? This would make contribution easier.

1) In component diagram, 2 grouping forms containing the same element name induce no element shown in the second form, ie. the naming scope is not hierarchical. Classes have namespaces (http://plantuml.sourceforge.net/classes.html#Namespaces), I wonder whether someone would come with such a need in component diagram one day.

@startuml
package AA {
  [XX]
}
package BB {
  [XX]
}
@enduml

2) In component diagram, 2 grouping forms named the same, first declared as container, then as one-liner yields 2 forms instead of only one.

@startuml
package CC {
  [YY]
}
package CC
@enduml
commented Sep 8, 2014 by rmric (2,140 points)
For anyone reading my last comment, the issue 1) can be worked-around by using aliases:

@startuml
package AA {
  [XX] as XX_in_AA
}
package BB {
  [XX] as XX_in_BB
}
@enduml

This is worth documenting in plantumldoc IMHO.
0 votes
answered Jan 15, 2014 by plantuml (294,660 points)

About hiding stereotype, this is already implemented:

http://plantuml.sourceforge.net/classes.html#Hide

So you can use:

@startuml
hide stereotype
class Foo<<Stereo1>>
class Dummy

skinparam class {
  backgroundColor red
  backgroundColor<<Stereo1>> yellow
}
@enduml



Is it ok for you ?
 

commented Jan 15, 2014 by rmric (2,140 points)
Yes, this is OK for me, and I took the inspiration from this page in my initial post. However, the hide keyword appears to work only in class diagrams. I'd like to have it working in component diagrams too, with the hide keyword itself stereotypable:

@startuml
skinparam component {
  backgroundColor<<hidden_st>> Yellow
  hide<<hidden_st>> stereotype
}

component HH <<hidden_st>>
component AA <<not_hidden_st>>
component BB
@enduml

Rem: the skinparam'd hide already kind of works for package, but only for package and not the other groupings, and it's missing the stereotyping capability.

Regards
commented Feb 20, 2017 by boshka (3,900 points)
Hi,
am I able to define a skinparam within a !definelong so that the skin style would only work within the function scope?
So that when the function returns, the modified skin parameters restores to the values, defined in the upper scope.
commented Feb 20, 2017 by plantuml (294,660 points)
Unfortunatly it's not possible.

Skin parameters cannot be changed several times within the same diagram. As you have probably noticed, only the last value applies.
Changing this would be quite difficult, so it's not in our plan now.
Sorry about that.
Maybe you can turn around this limitation using individual color settings ?
...