Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
hifis.net
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
HIFIS
Overall
hifis.net
Commits
c514d307
Verified
Commit
c514d307
authored
3 years ago
by
Huste, Tobias
Browse files
Options
Downloads
Patches
Plain Diff
Initial draft of a Kroki post
parent
c9fa8743
No related branches found
No related tags found
1 merge request
!229
Create a post announcing and explaining Kroki usage
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
_posts/2021/05/2021-05-21-diagrams-from-textual-descriptions.md
+480
-0
480 additions, 0 deletions
.../2021/05/2021-05-21-diagrams-from-textual-descriptions.md
with
480 additions
and
0 deletions
_posts/2021/05/2021-05-21-diagrams-from-textual-descriptions.md
0 → 100644
+
480
−
0
View file @
c514d307
---
title
:
"
GitLab
-
Create
Diagrams
From
Textual
Descriptions"
title_image
:
clark-tibbs-oqStl2L5oxI-unsplash.jpg
data
:
2021-05-21
authors
:
-
huste
layout
:
blogpost
categories
:
-
tutorials
excerpt
:
>
Recently, the Helmholtz-wide software development platform has been extended
with the ability to create diagrams from textual descriptions.
This post will help you getting started with this new feature.
---
{{ page.excerpt }}
## Quick-Start Example
Let us jump right in with an example by creating a UML sequence diagram.
Any of these examples can be used in a place on
<https://gitlab.hzdr.de>
where Markdown is supported:
*
Comments
*
Issues
*
Merge requests
*
Milestones
*
Snippets (the snippet must be named with a
`.md`
extension)
*
Wiki pages
*
Markdown documents inside repositories
Therefore, put this content describing the diagram in any of the items
listed above.
```plantuml
@startuml
participant User
User -> A: DoWork
activate A
A -> B: << createRequest >>
activate B
B -> C: DoWork
activate C
C --> B: WorkDone
destroy C
B --> A: RequestCreated
deactivate B
A -> User: Done
deactivate A
@enduml
```
This description is then converted into this sequence diagram.

## How Does That Work?
In the background a tool called
[
Kroki
](
https://kroki.io
)
is doing the magic.
It takes the textual description and converts it into an image.
The example shown above is using
[
PlantUML
](
https://plantuml.com/
)
to create
the diagram of our choice (see line 1).
So all you need to do is to create the textual description of your diagram and
put it into GitLab Markdown.
When viewing the content, in the background we will make sure that you are
presented an image of your diagram description.
## Step-By-Step Guide
In this example our goal is to create a visual representation of JSON data.
Let's take this example JSON data.
<details>
<summary>
Show JSON data
</summary>
<div
markdown=
1
>
```
json
{
"firstName"
:
"John"
,
"lastName"
:
"Smith"
,
"age"
:
28
,
"address"
:
{
"streetAddress"
:
"Bautzner Landstr. 400"
,
"city"
:
"Dresden"
,
"state"
:
"Saxony"
,
"postalCode"
:
"01328"
},
"offices"
:
[
{
"building"
:
512
,
"room"
:
1234
},
{
"building"
:
312
,
"room"
:
3
}
],
"departments"
:
[]
}
```
</div>
</details>
We will use PlantUML to
[
display the JSON data
](
https://plantuml.com/json
)
.
At first, we need to tell GitLab that we want to create a diagram using
PlantUML.
This is why we create a Markdown code block using PlantUML for syntax highlighting.
```plantuml
```
The
[
PlantUML documentation
](
https://plantuml.com/json
)
tells us how such a
visual representation can be created.
In this case you need to embed the JSON data into a block starting with
`@startjson`
and ending with
`@endjson`
.
```plantuml
@startjson
{
"firstName": "John",
"lastName": "Smith",
"age": 28,
"address": {
"streetAddress": "Bautzner Landstr. 400",
"city": "Dresden",
"state": "Saxony",
"postalCode": "01328"
},
"offices": [
{
"building": 512,
"room": 1234
},
{
"building": 312,
"room": 3
}
],
"departments": []
}
@endjson
```
You will be presented an image as shown below.

## What Else Can Be Done?
The new feature is not limited to using PlantUML.
The new integration gives you access to more than that.
It supports, among others,
[
Vega
](
https://github.com/vega/vega
)
,
[
C4 with PlantUML
](
https://github.com/RicardoNiepel/C4-PlantUML
)
,
[
GraphViz
](
https://www.graphviz.org/
)
or
[
BlockDiag
](
https://github.com/blockdiag/blockdiag
)
.
For a complete list please refer to the official
[
list of supported diagram types and formats
](
https://kroki.io/#support
)
.
### Vega
<details>
<summary>
Show code
</summary>
<div
markdown=
"1"
>
```
vega
{
"$schema": "https://vega.github.io/schema/vega/v5.json",
"description": "A nested bar chart example, with bars grouped by category.",
"width": 300,
"padding": 5,
"autosize": "pad",
"signals": [
{
"name": "rangeStep", "value": 20,
"bind": {"input": "range", "min": 5, "max": 50, "step": 1}
},
{
"name": "innerPadding", "value": 0.1,
"bind": {"input": "range", "min": 0, "max": 0.7, "step": 0.01}
},
{
"name": "outerPadding", "value": 0.2,
"bind": {"input": "range", "min": 0, "max": 0.4, "step": 0.01}
},
{
"name": "height",
"update": "trellisExtent[1]"
}
],
"data": [
{
"name": "tuples",
"values": [
{"a": 0, "b": "a", "c": 6.3},
{"a": 0, "b": "a", "c": 4.2},
{"a": 0, "b": "b", "c": 6.8},
{"a": 0, "b": "c", "c": 5.1},
{"a": 1, "b": "b", "c": 4.4},
{"a": 2, "b": "b", "c": 3.5},
{"a": 2, "b": "c", "c": 6.2}
],
"transform": [
{
"type": "aggregate",
"groupby": ["a", "b"],
"fields": ["c"],
"ops": ["average"],
"as": ["c"]
}
]
},
{
"name": "trellis",
"source": "tuples",
"transform": [
{
"type": "aggregate",
"groupby": ["a"]
},
{
"type": "formula", "as": "span",
"expr": "rangeStep * bandspace(datum.count, innerPadding, outerPadding)"
},
{
"type": "stack",
"field": "span"
},
{
"type": "extent",
"field": "y1",
"signal": "trellisExtent"
}
]
}
],
"scales": [
{
"name": "xscale",
"domain": {"data": "tuples", "field": "c"},
"nice": true,
"zero": true,
"round": true,
"range": "width"
},
{
"name": "color",
"type": "ordinal",
"range": "category",
"domain": {"data": "trellis", "field": "a"}
}
],
"axes": [
{ "orient": "bottom", "scale": "xscale", "domain": true }
],
"marks": [
{
"type": "group",
"from": {
"data": "trellis",
"facet": {
"name": "faceted_tuples",
"data": "tuples",
"groupby": "a"
}
},
"encode": {
"enter": {
"x": {"value": 0},
"width": {"signal": "width"}
},
"update": {
"y": {"field": "y0"},
"y2": {"field": "y1"}
}
},
"scales": [
{
"name": "yscale",
"type": "band",
"paddingInner": {"signal": "innerPadding"},
"paddingOuter": {"signal": "outerPadding"},
"round": true,
"domain": {"data": "faceted_tuples", "field": "b"},
"range": {"step": {"signal": "rangeStep"}}
}
],
"axes": [
{ "orient": "left", "scale": "yscale",
"ticks": false, "domain": false, "labelPadding": 4 }
],
"marks": [
{
"type": "rect",
"from": {"data": "faceted_tuples"},
"encode": {
"enter": {
"x": {"value": 0},
"x2": {"scale": "xscale", "field": "c"},
"fill": {"scale": "color", "field": "a"},
"strokeWidth": {"value": 2}
},
"update": {
"y": {"scale": "yscale", "field": "b"},
"height": {"scale": "yscale", "band": 1},
"stroke": {"value": null},
"zindex": {"value": 0}
},
"hover": {
"stroke": {"value": "firebrick"},
"zindex": {"value": 1}
}
}
}
]
}
]
}
```
</div>
</details>

Taken from
<https://vega.github.io/vega/examples/nested-bar-chart/>
.
### C4 with PlantUML
<details>
<summary>
Show code
</summary>
<div
markdown=
"1"
>
```
plantuml
@startuml "techtribesjs"
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
' uncomment the following line and comment the first to use locally
' !include C4_Container.puml
LAYOUT_TOP_DOWN()
'LAYOUT_AS_SKETCH()
LAYOUT_WITH_LEGEND()
Person_Ext(anonymous_user, "Anonymous User")
Person(aggregated_user, "Aggregated User")
Person(administration_user, "Administration User")
System_Boundary(c1, "techtribes.js"){
Container(web_app, "Web Application", "Java, Spring MVC, Tomcat 7.x", "Allows users to view people, tribes, content, events, jobs, etc. from the local tech, digital and IT sector")
ContainerDb(rel_db, "Relational Database", "MySQL 5.5.x", "Stores people, tribes, tribe membership, talks, events, jobs, badges, GitHub repos, etc.")
Container(filesystem, "File System", "FAT32", "Stores search indexes")
ContainerDb(nosql, "NoSQL Data Store", "MongoDB 2.2.x", "Stores from RSS/Atom feeds (blog posts) and tweets")
Container(updater, "Updater", "Java 7 Console App", "Updates profiles, tweets, GitHub repos and content on a scheduled basis")
}
System_Ext(twitter, "Twitter")
System_Ext(github, "GitHub")
System_Ext(blogs, "Blogs")
Rel(anonymous_user, web_app, "Uses", "HTTPS")
Rel(aggregated_user, web_app, "Uses", "HTTPS")
Rel(administration_user, web_app, "Uses", "HTTPS")
Rel(web_app, rel_db, "Reads from and writes to", "SQL/JDBC, port 3306")
Rel(web_app, filesystem, "Reads from")
Rel(web_app, nosql, "Reads from", "MongoDB wire protocol, port 27017")
Rel_U(updater, rel_db, "Reads from and writes data to", "SQL/JDBC, port 3306")
Rel_U(updater, filesystem, "Writes to")
Rel_U(updater, nosql, "Reads from and writes to", "MongoDB wire protocol, port 27017")
Rel(updater, twitter, "Gets profile information and tweets from", "HTTPS")
Rel(updater, github, "Gets information about public code repositories from", "HTTPS")
Rel(updater, blogs, "Gets content using RSS and Atom feeds from", "HTTP")
Lay_R(rel_db, filesystem)
@enduml
```
</div>
</details>

Taken from
<https://github.com/plantuml-stdlib/C4-PlantUML>
.
### GraphViz
<details>
<summary>
Show code
</summary>
<div
markdown=
"1"
>
{% raw %}
```
graphviz
digraph
G
{
concentrate
=
True
;
rankdir
=
TB
;
node
[
shape
=
record
]
;
140087530674552
[
label
=
"title: InputLayer\n|{input:|output:}|{{[(?, ?)]}|{[(? , ?)]}}"
]
;
140087537895856
[
label
=
"body: InputLayer\n|{input:|output:}|{{[(?, ?)]}|{[(?, ?)]}}"
]
;
140087531105640
[
label
=
"embedding_2: Embedding\n|{input:|output:}|{{(?, ?)}|{ (?, ?, 64)}}"
]
;
140087530711024
[
label
=
"embedding_3: Embedding\n|{input:|output:}|{{(?, ?)}|{ (?, ?, 64)}}"
]
;
140087537980360
[
label
=
"lstm_2: LSTM\n|{input:|output:}|{{(?, ?, 64)}|{(?, 128)}}"
]
;
140087531256464
[
label
=
"lstm_3: LSTM\n|{input:|output:}|{{(?, ?, 64)}|{(?, 32) }}"
]
;
140087531106200
[
label
=
"tags: InputLayer\n|{input:|output:}|{{[(?, 12)]}|{[(? , 12)]}}"
]
;
140087530348048
[
label
=
"concatenate_1: Concatenate\n|{input:|output:}|{{[(?, 128), (?, 32), (?, 12)]}|{(?, 172)}}"
]
;
140087530347992
[
label
=
"priority: Dense\n|{input:|output:}|{{(?, 172)}|{(?, 1) }}"
]
;
140087530711304
[
label
=
"department: Dense\n|{input:|output:}|{{(?, 172)}|{(?, 4)}}"
]
;
140087530674552
->
140087531105640
;
140087537895856
->
140087530711024
;
140087531105640
->
140087537980360
;
140087530711024
->
140087531256464
;
140087537980360
->
140087530348048
;
140087531256464
->
140087530348048
;
140087531106200
->
140087530348048
;
140087530348048
->
140087530347992
;
140087530348048
->
140087530711304
;
}
```
{%endraw%}
</div>
</details>

Taken from
<https://graphviz.org/Gallery/directed/neural-network.html>
.
### BlockDiag
<details>
<summary>
Show code
</summary>
<div
markdown=
"1"
>
```
blockdiag
blockdiag {
A -> B -> C -> D;
A -> E -> F -> G;
}
```
</div>
</details>

Taken from
<http://blockdiag.com/en/blockdiag/examples.html>
.
## Deployment
The service is provided by HIFIS Software and is hosted entirely on HZDR
servers.
It does not share any data with external providers.
As usual, the deployment can be reproduced via the corresponding
[
project
](
https://gitlab.hzdr.de/hifis-software-deployment/kroki
)
-
only accessible for employees within Helmhholtz.
## More Examples
More examples can be found in the
[
GitLab example project
](
https://gitlab.hzdr.de/examples/kroki
)
.
## Comments and Suggestions
If you have suggestions, questions, or queries, please don't hesitate to write us.
<a href="{% link contact.md %}"
class="btn btn-outline-secondary"
title="HIFIS Helpdesk">
Contact us!
<i
class=
"fas fa-envelope"
></i></a>
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment