Closed klu2 closed 2 years ago
Ah, probably even better would be to connect the sprite to ElementStyle.getIcon
, that would be quite generic, and we could easily add that to existing code without breaking anything - it would also conceptually make sense.
Ok for you if I create a PR for that?
3rd option would be to use AddElementTag
(which we could/should use anyways to also apply all other kinds of stylings) and pass the icon
to the sprite
here:
!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!include DEVICONS/msql_server.puml
!include DEVICONS/angular.puml
AddElementTag("MSQL", $sprite="msql_server")
AddElementTag("Angular", $sprite="angular")
:
Container(InternetBankingSystem.SinglePageApplication, "Single-Page Application", "JavaScript and Angular", "Provides all of the Internet banking functionality to customers via their web browser.", $tags="Element+Container+Web Browser+Angular")
ContainerDb(InternetBankingSystem.Database, "Database", "Oracle Database Schema", "Stores user registration information, hashed authentication credentials, access logs, etc.", $tags="Element+Container+Database+MSQL")
(and some more code) would result in:
And we could also use the properties from https://github.com/plantuml-stdlib/C4-PlantUML#custom-tagsstereotypes-support-and-skinparam-updates to pass all other kinds of properties (colors, bgcolor,...)
Hm. ElementStyle.setIcon
requires either a URL or a base64-encoded JPG or PNG as of ImageUtils.validateImage
, so passing the sprite name here is unfortunately no option
I've had discussions with others about support for sprites, and the most logical way to do this, and what everybody expects to happen, is to use whatever PNG/GIF icon is set for the element style (the icon
property). This will require converting the specified PNG/GIF to a sprite, which is a feature supported by PlantUML (java -jar plantuml.jar -encodesprite 16z foo.png
; see https://plantuml.com/sprite). Feel free to submit a PR for this, but please don't add a dependency on the GPL version of PlantUML.
And you're also correct, another alternative that doesn't require any code changes is to create your own include that defines a number of tags. For example, this will work now -> demo.
!define DEVICONS https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons
!include DEVICONS/msql_server.puml
AddElementTag("MSQL", $sprite="msql_server")
workspace "Getting Started" "This is a model of my software system." {
model {
softwareSystem = softwareSystem "Software System" {
tags "MSQL"
}
}
views {
properties {
"plantuml.includes" "https://gist.githubusercontent.com/simonbrowndotje/70c5a3ca611d06e6247f2a7ba936901c/raw/3026104850ff55fd13cb9d75b51e1c7b9e786ee7/include.puml"
}
systemLandscape {
include *
autoLayout
}
}
}
Well, that would require users to publish their .puml
files to a webserver, that makes it complicated.
What about reusing ModelItem.addProperty
?
Code could look like that (in Java):
Container container = softwareSystem.addContainer("Web Application", "", "Angular");
container.addProperty(C4PlantUMLExporter.PLANTUML_SPRITE_PROPERTY, "angular");
workspace.views.addProperty(
C4PlantUMLExporter.PLANTUML_INCLUDES_PROPERTY,
"https://raw.githubusercontent.com/tupadr3/plantuml-icon-font-sprites/master/devicons/angular.puml"
);
And in C4PlantUMLExporter.writeElement
you check the properties of the current ModelItem
, and if a key C4PlantUMLExporter.PLANTUML_SPRITE_PROPERTY
exists, then we add the $sprite
there directly. That would also have the big advantage that we would not extensively create tags (which would be shown in the legend then) just to draw some icons.
And when doing that, we could take care of https://github.com/structurizr/export/issues/2 as well (and remove the sprite-property then)
Nevertheless, we could/should add support for AddElementTag
as described above as well, but that could go to a separate ticket as well.
What do you think?
Well, that would require users to publish their .puml files to a webserver, that makes it complicated.
I think !include
can reference local files, and I imagine that most users have PlantUML installed locally anyway.
What about reusing ModelItem.addProperty ?
I'd rather not do that, as (1) it mixes content with presentation and (2) it bypasses the existing element style mechanism, which is what everybody is expecting to use.
My preference would be to automatically convert the element style icon to a sprite, since that's what users are already expecting should happen. If that's too much work, I'd be happy to add the ability to set name/value properties on the ElementStyle
and RelationshipStyle
classes, which you could use for setting sprite names.
I imagine that most users have PlantUML installed locally anyway.
Not in our case - we would use a Confluence macro to render the puml
files, and those need to be self-contained (or reference data from a webserver)
I'd be happy to add the ability to set name/value properties on the ElementStyle and RelationshipStyle classes, which you could use for setting sprite names.
If you could do that in structurizr-core, that would be great - I'll add support then in the exporter.
I saw you added that already to structurizr-core (https://github.com/structurizr/java/commit/783ff48f0251ceea966e6fd61397913b5837e441), still waiting for the release to MavenCentral - do you have a time plan for that already?
No release plan yet. BTW, did you see the following?
yes, I'm currently about to release a separate java library containing Icons of all kinds as URL, Base64-Strings and PlantUML-Sprites, and URLs and Base64 versions could then also be injected to ElementStyle.setIcon()
, so basically we would not have the need for Sprites at all then.
@klu2 Are you still working on it? I want to give it a try using $sprite="img:data:image/png;base64,...."
@klu2 Are you still working on it? I want to give it a try using
$sprite="img:data:image/png;base64,...."
I published https://github.com/cloudflightio/structurizr-export-c4plantuml which allows you to use not only tags and properties, but you can use that also to apply themes. Check the readme there, it comes with an example.
Support for sprites has now been added; see https://github.com/structurizr/export/issues/21 for details.
PlantUML allows to pass sprites to diagrams in order to have all kinds of logos in the generated diagrams, see https://github.com/plantuml-stdlib/C4-PlantUML#getting-started
In the code that looks like that:
which results in such a diagram:
It would be great to have that in the
C4PlantUMLExporter
.Adding separate includes is already possible via
com.structurizr.export.plantuml.AbstractPlantUMLExporter#PLANTUML_INCLUDES_PROPERTY
, what we need to achieve is to add the sprites somehow from the model.I thought a bit how that could be integrated into the method
com.structurizr.export.plantuml.C4PlantUMLExporter#writeElement
without breaking things. We could of course pass the content ofcontainer.getTechnology()
orcomponent.getTechnology()
as sprite to thewriter
but that will make the diagram look weird when no sprite can be found for a given technology (besides that I don't know if a technology is always the best indicator for a sprite).I'd therefore extract the code which finally writes the Container or Component to the writer to a strategy interface which can be exchanged by clients, leaving the default-implementation as-is in the current repo in order to not break existing things.
If you want I can provide a PR how that could look like.
Probably I could catch https://github.com/structurizr/export/issues/2 then as well.