Obsah
1. Tvorba diagramů s architekturou systémů s využitím knihovny Diagrams
2. Instalace knihovny Diagrams
3. První demonstrační příklad – vývojový diagram s dvojicí uzlů
4. Přidání dalších typů uzlů do vývojového diagramu
6. Přímé zobrazení diagramu po spuštění skriptu
7. Diagram se zobrazením jednoduché pipeline
8. Diagram s větvením a spojením – větší množství workerů
9. Vertikální orientace předchozího diagramu
10. Složitější pipeline s větším množstvím větvení
11. Větší množství zdrojů dat v pipeline
12. Uzel, který je umístěn současně na začátku i na konci toku dat
13. Možná oprava – použití stejného uzlu v diagramu dvakrát
14. Alternativní architektura – zápis dat do Kafky a současně i do databáze
15. Vytvoření clusterů v diagramu
16. Typy uzlů podporované knihovnou Diagrams
18. Repositář s demonstračními příklady
19. Odkazy na články s tématem programové tvorby grafů a diagramů
1. Tvorba diagramů s architekturou systémů s využitím knihovny Diagrams
V předchozí trojici článků [1] [2] [3] jsme se zabývali diagramy, které jsou do jisté míry (či zcela) standardizovány a mnohdy i spjaty s nějakou normou či specifikací (vývojové diagramy, UML v případě sekvenčních diagramů), popř. jsou postaveny nad grafy používanými přímo v matematice (orientované a neorientované grafy). Dnes se budeme zabývat knihovnou nazvanou Diagrams, která umožňuje vytvářet obecné diagramy, jež se mnohdy používají pro zobrazení architektury vytvářeného systému. Autoři těchto diagramů mají většinou mnohem více volnosti při určení, jaké uzly a jaké hrany („šipky“) budou v takovém diagramu použity. Je zcela v pořádku vynechat některé uzly (například logovací službu) i některé šipky naznačující řízení, popř. tok dat. Tyto diagramy se velmi snadno tvoří buď interaktivně (http://draw.io) nebo právě s využitím knihovny Diagrams, s níž se dnes seznámíme.
Obrázek 1: Příklad diagramu s architekturou aplikace založené na mikroslužbách propojených s využitím message brokerů.
2. Instalace knihovny Diagrams
Knihovna Diagrams je dostupná na PyPI, takže je její instalace velmi snadná a přímočará. Postačuje použít nástroj pip, resp. pip3 (podle konfigurace vašeho systému):
$ pip install diagrams Collecting diagrams Downloading diagrams-0.19.1-py3-none-any.whl (19.2 MB) |████████████████████████████████| 19.2 MB 3.0 MB/s Collecting graphviz<0.17.0,>=0.13.2 Downloading graphviz-0.16-py2.py3-none-any.whl (19 kB) Collecting jinja2<3.0,>=2.10 Downloading Jinja2-2.11.3-py2.py3-none-any.whl (125 kB) |████████████████████████████████| 125 kB 25.0 MB/s Requirement already satisfied: MarkupSafe>=0.23 in /usr/lib/python3/dist-packages (from jinja2<3.0,>=2.10->diagrams) (1.1.0) Installing collected packages: graphviz, jinja2, diagrams Successfully installed diagrams-0.19.1 graphviz-0.16 jinja2-2.11.3
Nyní je již snadné nechat si zobrazit nápovědu, a to přímo v interaktivní smyčce REPL programovacího jazyka Python. Následuje příklad nápovědy pro uzel pojmenovaný StartEnd, což je třída definovaná v balíčku diagrams.programming.flowchart:
Help on class StartEnd in module diagrams.programming.flowchart: class StartEnd(_Flowchart) | StartEnd(label: str = '', **attrs: Dict) | | Node represents a node for a specific backend service. | | Method resolution order: | StartEnd | _Flowchart | diagrams.programming._Programming | diagrams.Node | builtins.object | | Data and other attributes inherited from diagrams.programming._Programming: | | fontcolor = '#ffffff' | | ---------------------------------------------------------------------- | Methods inherited from diagrams.Node: | | __init__(self, label: str = '', **attrs: Dict) | Node represents a system component.
3. První demonstrační příklad – vývojový diagram s dvojicí uzlů
V dnešním prvním demonstračním příkladu je ukázán vývojový diagram, který obsahuje pouze dva uzly naznačující počátek a konec zpracování. Tyto uzly jsou představovány objekty typu diagrams.programming.flowchart.StartEnd a jsou spojeny s využitím operátoru >>. Povšimněte si způsobu vytvoření diagramu s využitím bloku with, což je do značné míry podobné způsobu který jsme si ukázali v souvislosti s knihovnou pyflowchart:
from diagrams import Diagram from diagrams.programming.flowchart import StartEnd # novy graf s urcenim jeho zakladnich vlastnosti with Diagram("Flow chart #1", show=False): # definice uzlu grafu start = StartEnd("Start") end = StartEnd("End") # propojeni uzlu grafu orientovanymi hranami start >> end
Po spuštění tohoto demonstračního příkladu by se měl vytvořit rastrový obrázek s tímto obsahem:
Obrázek 2: Vývojový diagram, který obsahuje pouze uzly s počátkem a koncem zpracování.
4. Přidání dalších typů uzlů do vývojového diagramu
Do vývojového diagramu je pochopitelně možné přidat i další typy uzlů. Jedná se o uzel představující dílčí krok zpracování (tedy operaci) představovaný objektem diagrams.programming.flowchart.Action a dále o uzel se vstupně-výstupní operací, jenž je představován objektem typu diagrams.programming.flowchart.InputOutput:
from diagrams import Diagram from diagrams.programming.flowchart import StartEnd from diagrams.programming.flowchart import InputOutput from diagrams.programming.flowchart import Action # novy graf s urcenim jeho zakladnich vlastnosti with Diagram("Flow chart #2", show=False): # definice uzlu start = StartEnd("Start") input = InputOutput("radius=") computation = Action("area=pi*radius^2") display = InputOutput("circle area=area") end = StartEnd("End") # propojeni uzlu grafu orientovanymi hranami >> input >> computation >> display >> end
Všechny uzly jsou opět propojeny operací >>, přičemž výsledek by měl vypadat následovně:
Obrázek 3: Vývojový diagram s uzly typu Action a InputOutput.
5. Změna orientace diagramu
Vývojové diagramy (ale i další typy diagramů) jsou většinou orientovány tak, že další operace se nachází pod operací předchozí. Tohoto chování je možné při použití knihovny Diagrams dosáhnout velmi snadno, což je ukázáno na dalším demonstračním příkladu. Postačuje při konstrukci objektu typu diagrams.Diagram použít nepovinný parametr direction a nastavit ho na hodnotu „TB“, neboli „Top-Bottom“:
from diagrams import Diagram from diagrams.programming.flowchart import StartEnd from diagrams.programming.flowchart import InputOutput from diagrams.programming.flowchart import Action # novy graf s urcenim jeho zakladnich vlastnosti with Diagram("Flow chart #3", show=False, direction="TB"): # definice uzlu start = StartEnd("Start") input = InputOutput("radius=") computation = Action("area=pi*radius^2") display = InputOutput("circle area=area") end = StartEnd("End") # propojeni uzlu grafu orientovanymi hranami start >> input >> computation >> display >> end
Nyní bude výsledek následující:
Obrázek 4: Diagram s nastavenou orientací Top-Bottom.
6. Přímé zobrazení diagramu po spuštění skriptu
Diagram vytvořený v rámci Pythonovského skriptu je možné zobrazit ihned po dokončení skriptu, přesněji řečeno ihned poté, co se ukončí platnost bloku with s definicí diagramu. Aby se zobrazení diagramu skutečně provedlo, je nutné při konstrukci objektu typu diagrams.Diagram specifikovat nepovinný parametr show a nastavit ho (podle očekávání) na hodnotu True, což je ostatně ukázáno v dalším demonstračním příkladu:
from diagrams import Diagram from diagrams.programming.flowchart import StartEnd from diagrams.programming.flowchart import InputOutput from diagrams.programming.flowchart import Action # novy graf s urcenim jeho zakladnich vlastnosti with Diagram("Flow chart #4", show=True, direction="TB"): # definice uzlu start = StartEnd("Start") input = InputOutput("radius=") computation = Action("area=pi*radius^2") display = InputOutput("circle area=area") end = StartEnd("End") # propojeni uzlu grafu orientovanymi hranami start >> input >> computation >> display >> end
Výsledek získaný spuštěním tohoto příkladu:
Obrázek 5: Totožný diagram, jako v předchozím příkladu, ovšem současně zobrazený ihned po spuštění skriptu.
7. Diagram se zobrazením jednoduché pipeline
Předností knihovny Diagrams je podpora velkého množství typů uzlů, přičemž každý uzel je tvořen určitou ikonou s případným popiskem uvedeným u této ikony (typicky pod ikonou). U výše ukázaných vývojových diagramů se jednalo spíše o špatný koncept, protože vývojové diagramy jsou navrženy takovým způsobem, aby byly popisky zapsány přímo do uzlu. Naproti tomu u diagramů naznačujících architekturu aplikace tomu je poněkud jinak. Ukažme si nyní způsob zobrazení diagramu s jednoduchou pipeline tvořenou Kafkou (resp. tématem – topicem), dále workerem naprogramovaným v jazyce Go a následně výstupní frontou realizovanou message brokerem RabbitMQ. Ikony s těmito uzly jsou importovány z různých balíčků:
from diagrams import Diagram from diagrams.onprem.queue import Kafka, Rabbitmq from diagrams.programming.language import Go # novy graf s urcenim jeho zakladnich vlastnosti with Diagram("OnPrem #1", show=True): # definice uzlu consumer = Kafka("input stream") worker = Go("worker") producer = Rabbitmq("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> worker >> producer
S tímto výsledkem:
Obrázek 6: Jednoduchá pipeline tvořená Kafkou, workerem naprogramovaným v Go a message brokerem RabbitMQ.
8. Diagram s větvením a spojením – větší množství workerů
Nyní se dostáváme k velmi zajímavé vlastnosti knihovny Diagrams – ke snadnému vytvoření diagramu, v němž dochází k větvení či naopak ke spojení jednotlivých cest. Realizace je přitom velmi snadná, protože pouze dostačuje, aby se namísto jednoho uzlu specifikoval seznam uzlů. Při napojení tohoto seznamu na další uzly knihovna Diagrams sama zajistí rozvětvení (uzel→seznam) či naopak spojení (seznam→uzel), což je ukázáno na dalším příkladu s větším množstvím workerů:
from diagrams import Diagram from diagrams.onprem.queue import Kafka, Rabbitmq from diagrams.programming.language import Go # novy graf s urcenim jeho zakladnich vlastnosti with Diagram("OnPrem #2", show=True): # definice uzlu consumer = Kafka("input stream") # rozvetveni workers = [Go("worker #1"), Go("worker #2"), Go("worker #3")] # a spojeni producer = Rabbitmq("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> workers >> producer
Obrázek 7: Diagram s rozvětvením a spojením.
Pro zajímavost se nyní podívejme na to, jak lze naprosto stejný diagram realizovat s využitím odlišných ikon a tím pádem i jiných typů uzlů. Nyní tu stejnou architekturu aplikace „přeneseme“ do AWS, kde se namísto Kafky a RabbitMQ použije SQS a i workeři jsou realizováni jinou technologií:
from diagrams import Diagram from diagrams.aws.compute import EC2 from diagrams.aws.integration import SQS # novy graf s urcenim jeho zakladnich vlastnosti with Diagram("AWS", show=True, direction="TB"): # definice uzlu consumer = SQS("input stream") # rozvetveni workers = [EC2("worker #1"), EC2("worker #2"), EC2("worker #3")] # a spojeni producer = SQS("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> workers >> producer
Obrázek 8: Diagram s rozvětvením a spojením, ovšem používajícím odlišné ikony.
9. Vertikální orientace předchozího diagramu
Diagram, který jsme vytvořili v rámci předchozí kapitoly, je možné orientovat i vertikálně, tedy (většinou) shora dolů. Tato možnost je ukázána v následujícím demonstračním příkladu, který se od předchozího příkladu liší pouze nepovinným parametrem direction:
from diagrams import Diagram from diagrams.onprem.queue import Kafka, Rabbitmq from diagrams.programming.language import Go with Diagram("OnPrem #3", show=True, direction="TB"): # definice uzlu consumer = Kafka("input stream") # rozvetveni workers = [Go("worker #1"), Go("worker #2"), Go("worker #3")] producer = Rabbitmq("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> workers >> producer
Výsledkem činnosti předchozího skriptu bude tento diagram:
Obrázek 9: Diagram orientovaný vertikálně (shora dolů).
from diagrams import Diagram from diagrams.onprem.queue import Kafka, Rabbitmq from diagrams.programming.language import Go with Diagram("OnPrem #3", show=True, direction="BT"): # definice uzlu consumer = Kafka("input stream") # rozvetveni workers = [Go("worker #1"), Go("worker #2"), Go("worker #3")] producer = Rabbitmq("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> workers >> producer
Obrázek 10: Diagram orientovaný vertikálně (zdola nahoru).
10. Složitější pipeline s větším množstvím větvení
Celá pipeline (a zobrazená aplikace, resp. systém vlastně není nic jiného, než pipeline) může být v praxi i výrazně složitější. Je to ukázáno na dalším demonstračním příkladu, v němž jsou použity dvě skupiny workerů, které jsou propojeny s využitím message brokera ActiveMQ, který zde slouží v roli fronty (resp. bufferu):
from diagrams import Diagram from diagrams.onprem.queue import Kafka, ActiveMQ from diagrams.programming.language import Go, Rust with Diagram("OnPrem #4", show=True, direction="TB"): # definice uzlu consumer = Kafka("input stream") # rozvetveni workersA = [Go("worker #1"), Go("worker #2"), Go("worker #3")] buffer = ActiveMQ("buffer") # rozvetveni workersB = [Rust("worker #1"), Rust("worker #2"), Rust("worker #3")] producer = Kafka("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> workersA >> buffer >> workersB >> producer
Výsledek by mohl vypadat následovně:
Obrázek 11: Složitější pipeline s větším množstvím větvení.
11. Větší množství zdrojů dat v pipeline
Dalším (v praxi poměrně typickým) příkladem může být architektura, v níž se vyskytuje větší množství zdrojů dat, tedy (z hlediska diagramu) uzlů umístěných na začátku grafu. V tomto případě lze použít následující trik:
# zdroje dat consumer = Kafka("input stream") db = RDS("storage") # skupina workerů workersA = [Go("worker #1"), Go("worker #2"), Go("worker #3")] # propojeni uzlu grafu orientovanymi hranami consumer >> workersA db >> workersA
Úplný tvar takto upraveného demonstračního příkladu vypadá takto:
from diagrams import Diagram from diagrams.onprem.queue import Kafka, ActiveMQ from diagrams.programming.language import Go, Rust from diagrams.aws.database import RDS with Diagram("OnPrem #5", show=True, direction="TB"): # definice uzlu consumer = Kafka("input stream") db = RDS("storage") # rozvetveni workersA = [Go("worker #1"), Go("worker #2"), Go("worker #3")] buffer = ActiveMQ("buffer") # rozvetveni workersB = [Rust("worker #1"), Rust("worker #2"), Rust("worker #3")] producer = Kafka("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> workersA >> buffer >> workersB >> producer db >> workersA
Výsledek:
Obrázek 12: Větší množství zdrojů dat v pipeline.
12. Uzel, který je umístěn současně na začátku i na konci toku dat
V případě, že do diagramu umístíme uzel, který je současně na začátku i na konci toku dat, může být algoritmus rozmisťující uzly do diagramu zmaten a uzly budou ve výsledku zpřeházené. Můžeme si to ukázat na dalším demonstračním příkladu, v němž je uzel db použit jako zdroj dat i jako jejich cíl:
from diagrams import Diagram from diagrams.onprem.queue import Kafka, ActiveMQ from diagrams.programming.language import Go, Rust from diagrams.aws.database import RDS with Diagram("OnPrem #6", show=True, direction="TB"): # definice uzlu consumer = Kafka("input stream") db = RDS("storage") # rozvetveni workersA = [Go("worker #1"), Go("worker #2"), Go("worker #3")] buffer = ActiveMQ("buffer") # rozvetveni workersB = [Rust("worker #1"), Rust("worker #2"), Rust("worker #3")] producer = Kafka("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> workersA >> buffer >> workersB >> producer db >> workersA producer >> db
Výsledek v tomto případě asi nebude zcela odpovídat představám autora:
Obrázek 13: Uzel, který je umístěn současně na začátku i na konci toku dat.
13. Možná oprava – použití stejného uzlu v diagramu dvakrát
Uzel, který reprezentuje jak zdroj, tak i cíl dat, je pochopitelně možné zdvojit – tedy vložit do grafu dva uzly se stejnou ikonou i popisem. Jeden z těchto uzlů bude reprezentovat pouze zdroj dat, druhý pak cíl, tedy tak, jak je to ukázáno na následujícím úryvku kódu:
db1 = RDS("storage") db2 = RDS("storage") # propojeni uzlu grafu orientovanymi hranami db1 >> workersA ... ... ... ... ... ... producer >> db2
Upravený skript bude vypadat následovně:
from diagrams import Diagram from diagrams.onprem.queue import Kafka, ActiveMQ from diagrams.programming.language import Go, Rust from diagrams.aws.database import RDS with Diagram("OnPrem #7", show=True, direction="TB"): # definice uzlu consumer = Kafka("input stream") db1 = RDS("storage") db2 = RDS("storage") # rozvetveni workersA = [Go("worker #1"), Go("worker #2"), Go("worker #3")] buffer = ActiveMQ("buffer") # rozvetveni workersB = [Rust("worker #1"), Rust("worker #2"), Rust("worker #3")] producer = Kafka("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> workersA >> buffer >> workersB >> producer db1 >> workersA producer >> db2
Pochopitelně se změní i obrázek s výsledným grafem:
Obrázek 14: Uzel „Storage“ je v grafu zdvojen – je použit jak na začátku, tak i na konci celé architektury.
14. Alternativní architektura – zápis dat do Kafky a současně i do databáze
Následuje další příklad diagramu s architekturou aplikace. Tentokrát se ovšem výsledná data zapisují jak do systému Apache Kafka, tak i do databáze. Jedná se o velmi často používanou architekturu, protože do Kafky se většinou zapisují pouze notifikace o (potenciálně větších) datech, které jsou zapsány do objektové nebo dokumentové databáze (ale samozřejmě lze použít i klasickou databázi relační):
from diagrams import Diagram from diagrams.onprem.queue import Kafka, ActiveMQ from diagrams.programming.language import Go, Rust from diagrams.aws.database import RDS with Diagram("OnPrem #8", show=True, direction="TB"): # definice uzlu consumer = Kafka("input stream") db1 = RDS("storage") db2 = RDS("storage") # rozvetveni workersA = [Go("worker #1"), Go("worker #2"), Go("worker #3")] buffer = ActiveMQ("buffer") # rozvetveni workersB = [Rust("worker #1"), Rust("worker #2"), Rust("worker #3")] producer = Kafka("output stream") # propojeni uzlu grafu orientovanymi hranami consumer >> workersA >> buffer >> workersB >> producer db1 >> workersA workersB >> db2
Výsledný diagram s navrženou architekturou:
Obrázek 15: Zápis výsledných dat do Kafky a současně i do databáze.
15. Vytvoření clusterů v diagramu
Uzly je možné v případě potřeby sdružit do takzvaných clusterů. Vzhledem k tomu, že do clusteru bude vždy patřit ucelená část grafu, je cluster definován v rámci bloku with, protože na cluster se můžeme (z pohledu programovacího jazyka Python) dívat jako na kontext. Ukažme si nyní demonstrační příklad, který byl získán přímo z oficiálních příkladů na stránce nástroje Diagrams. V tomto diagramu je vytvořeno několik clusterů, které jsou navíc hierarchické – jeden cluster může obsahovat další cluster(y):
from diagrams import Cluster, Diagram from diagrams.aws.compute import ECS, EKS, Lambda from diagrams.aws.database import Redshift from diagrams.aws.integration import SQS from diagrams.aws.storage import S3 with Diagram("Event Processing", show=False): source = EKS("k8s source") with Cluster("Event Flows"): with Cluster("Event Workers"): workers = [ECS("worker1"), ECS("worker2"), ECS("worker3")] queue = SQS("event queue") with Cluster("Processing"): handlers = [Lambda("proc1"), Lambda("proc2"), Lambda("proc3")] store = S3("events store") dw = Redshift("analytics") source >> workers >> queue >> handlers handlers >> store handlers >> dw
Výsledek:
Obrázek 16: Clustery v diagramu.
16. Typy uzlů podporované knihovnou Diagrams
Knihovna Diagrams podporuje velké množství uzlů, které většinou reprezentují nějakou službu či nástroj používaný v oblasti mikroslužeb. Tomu ostatně odpovídají i názvy balíčků, v nichž jsou uzly definovány. Každý typ uzlu je představován samostatnou třídou a platí, že v jednom grafu je možné kombinovat libovolné uzly (i když to mnohdy nemusí být smysluplné):
Oblast |
---|
OnPrem |
AWS |
Azure |
GCP |
K8S |
AlibabaCloud |
OCI |
OpenStack |
Firebase |
Outscale |
Elastic |
Generic |
Programming |
Saas |
Grafické reprezentace uzlů (což jsou ve skutečnosti rastrové obrázky ve formátu PNG) nejsou nainstalovány společně s knihovnou Diagrams. Až při prvním použití uzlu je soubor s grafickou reprezentací uzlu stažen a uložen do adresáře ~/.local/lib/pythonX.Y/site-packages/resources/. Při testování knihovny Diagrams si tedy dejte pozor na to, že tento adresář může nepříjemně narůstat. Navíc pokud se v průběhu generování diagramu hlásí chyby, může to být způsobeno nastavením firewallu.
17. Obsah navazujícího článku
V navazujícím článku nejdříve dokončíme popis možností knihovny Diagrams a poté se seznámíme s další podobně koncipovanou knihovnou, tentokrát ovšem určenou pro programovací jazyk Go. Jedná se o knihovnu pojmenovanou go-diagrams. Tato knihovna je navržena takovým způsobem, aby byla s původní Pythonovskou knihovnou Diagrams do určité míry kompatibilní, což se týká především způsobu definice diagramů:
package main import ( "log" "github.com/blushft/go-diagrams/diagram" ) func main() { // inicializace objektu představujícího diagram diagram, err := diagram.New(diagram.Label("Diagram #1"), diagram.Filename("diagram1")) // kontrola konstrukce objektu if err != nil { log.Fatal(err) } // vykreslení diagramu err = diagram.Render() // kontrola, zda bylo vykreslení provedeno bez chyby if err != nil { log.Fatal(err) } }
18. Repositář s demonstračními příklady
Zdrojové kódy všech dnes popsaných demonstračních příkladů určených pro Python 3 byly uloženy do Git repositáře dostupného na adrese https://github.com/tisnik/most-popular-python-libs. V případě, že nebudete chtít klonovat celý repositář (ten je ovšem stále velmi malý, dnes má velikost zhruba několik desítek kilobajtů), můžete namísto toho použít odkazy na jednotlivé příklady, které naleznete v následující tabulce:
19. Odkazy na články s tématem programové tvorby grafů a diagramů
V této kapitole jsou uvedeny odkazy na předchozí články, v nichž jsme se zabývali tvorbou různých typů grafů a diagramů – a to v naprosté většině případů s využitím nějakého doménově specifického jazyka neboli DSL (Domain Specific Language), popř. nějakého univerzálního programovacího jazyka:
- Nástroje pro tvorbu UML diagramů
https://www.root.cz/clanky/nastroje-pro-tvorbu-uml-diagramu/ - Nástroje pro tvorbu UML diagramů z příkazové řádky
https://www.root.cz/clanky/nastroje-pro-tvorbu-uml-diagramu-z-prikazove-radky/ - Nástroje pro tvorbu UML diagramů z příkazové řádky (II)
https://www.root.cz/clanky/nastroje-pro-tvorbu-uml-diagramu-z-prikazove-radky-ii/ - Nástroje pro tvorbu grafů a diagramů z příkazové řádky
https://www.root.cz/clanky/nastroje-pro-tvorbu-grafu-a-diagramu-z-prikazove-radky/ - Sledování správy paměti v Pythonu s využitím nástroje objgraph
https://www.root.cz/clanky/sledovani-spravy-pameti-v-pythonu-s-vyuzitim-nastroje-objgraph/ - Programová tvorba diagramů v jazyku Clojure s využitím knihovny Rhizome
https://www.root.cz/clanky/programova-tvorba-diagramu-v-jazyku-clojure-s-vyuzitim-knihovny-rhizome/ - Tvorba sekvenčních diagramů v Pythonu s využitím knihovny Napkin
https://www.root.cz/clanky/tvorba-sekvencnich-diagramu-v-pythonu-s-vyuzitim-knihovny-napkin/ - Tvorba vývojových diagramů přímo ze zdrojových kódů Pythonu
https://www.root.cz/clanky/tvorba-vyvojovych-diagramu-primo-ze-zdrojovych-kodu-pythonu/
20. Odkazy na Internetu
- Flowchart (Wikipedia)
https://en.wikipedia.org/wiki/Flowchart - DRAKON
https://en.wikipedia.org/wiki/DRAKON - Modeling language
https://en.wikipedia.org/wiki/Modeling_language - Napkin na GitHubu
https://github.com/pinetr2e/napkin - Napkin 0.6.8 na PyPi
https://pypi.org/project/napkin/ - PlantUML (home page)
http://plantuml.sourceforge.net/ - PlantUML (download page)
http://sourceforge.net/projects/plantuml/files/plantuml.jar/download - PlantUML (Language Reference Guide)
http://plantuml.sourceforge.net/PlantUML_Language_Reference_Guide.pdf - Rhizome
https://github.com/ztellman/rhizome - Swagger to UML
https://github.com/nlohmann/swagger_to_uml - pydiagrams
https://github.com/billingtonm/pydiagrams - graphviz(3) – Linux man page
https://linux.die.net/man/3/graphviz - dot(1) – Linux man page
https://linux.die.net/man/1/dot - neato(1) – Linux man page
https://linux.die.net/man/1/neato - twopi(1) – Linux man page
https://linux.die.net/man/1/twopi - circo(1) – Linux man page
https://linux.die.net/man/1/circo - fdp(1) – Linux man page
https://linux.die.net/man/1/fdp - sfdp(1) – Linux man page
https://linux.die.net/man/1/sfdp - Plain-text diagrams take shape in Asciidoctor!
http://asciidoctor.org/news/2014/02/18/plain-text-diagrams-in-asciidoctor/ - Graphviz – Graph Visualization Software
http://www.graphviz.org/ - graphviz (Manual Page)
http://www.root.cz/man/7/graphviz/ - dot (Manual page)
http://www.root.cz/man/1/dot/ - dot (Manual v PDF)
https://graphviz.org/pdf/dot.1.pdf - Ditaa home page
http://ditaa.sourceforge.net/ - Ditaa introduction
http://ditaa.sourceforge.net/#intro - Ditaa usage
http://ditaa.sourceforge.net/#usage - Node, Edge and Graph Attributes
http://www.graphviz.org/doc/info/attrs.html - Graphviz (Wikipedia)
http://en.wikipedia.org/wiki/Graphviz - Unified Modeling Language
https://en.wikipedia.org/wiki/Unified_Modeling_Language - UML basics: The sequence diagram
http://www.ibm.com/developerworks/rational/library/3101.html - UML 2 State Machine Diagrams: An Agile Introduction
http://www.agilemodeling.com/artifacts/stateMachineDiagram.htm - Sequence diagram (Wikipedia)
https://en.wikipedia.org/wiki/Sequence_diagram - UML 2 Sequence Diagrams: An Agile Introduction
http://www.agilemodeling.com/artifacts/sequenceDiagram.htm - A Quick Introduction to UML Sequence Diagrams
http://www.tracemodeler.com/articles/a_quick_introduction_to_uml_sequence_diagrams/ - UML Sequence Diagrams
https://www.uml-diagrams.org/sequence-diagrams.html - Web Sequence Diagrams
https://www.websequencediagrams.com/ - Drawing sequence diagrams “napkin style”
https://modeling-languages.com/drawing-sequence-diagrams-napkin-style/ - Curated list of UML tools – 2020 edition
https://modeling-languages.com/uml-tools/#textual - Flowchart diagrams vs. UML activity diagrams
https://stackoverflow.com/questions/7081215/flowchart-diagrams-vs-uml-activity-diagrams - Kopenograms – Graphical Language for Structured Algorithms
https://kopenogram.org/Assets/Kopenograms_Graphical_Language_for_Structured_Algorithms.pdf - Kopenograms and Their Implementation in BlueJ
https://link.springer.com/chapter/10.1007%2F978–3–319–46535–7_8 - The simplest way to describe your flows
https://code2flow.com/ - Allan Mogensen and his Legacy
http://www.worksimp.com/articles/allan-mogensen.htm - Diagrams: Diagram as Code
https://diagrams.mingrammer.com/ - Diagrams: Guides
https://diagrams.mingrammer.com/docs/guides/diagram - Diagrams: Nodes
https://diagrams.mingrammer.com/docs/nodes/onprem - go-diagrams
https://github.com/blushft/go-diagrams - GoJS
https://gojs.net/latest/index.html - Code visualization: How to turn complex code into diagrams
https://www.lucidchart.com/blog/visualize-code-documentation - Create dependency diagrams from your code
https://docs.microsoft.com/en-us/visualstudio/modeling/create-layer-diagrams-from-your-code?view=vs-2019 - Software Architecture Diagrams as Code
https://shekhargulati.com/2020/04/21/software-architecture-diagrams-as-code/