Tvorba diagramů s architekturou systémů s využitím knihovny Diagrams

25. 5. 2021
Doba čtení: 21 minut

Sdílet

 Autor: Pavel Tišnovský
Dnes si představíme knihovnu nazvanou Diagrams. S využitím této knihovny lze vytvářet diagramy s architekturou navrhovaných systémů, čehož lze využít například v oblasti mikroslužeb.

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

5. Změna orientace 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

17. Obsah navazujícího článku

18. Repositář s demonstračními příklady

19. Odkazy na články s tématem programové tvorby grafů a diagramů

20. Odkazy na Internetu

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
Poznámka: povšimněte si, že se skutečně nainstalovalo i rozhraní pro GraphViz.

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.flow­chart.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.flow­chart.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.

Poznámka: styl vykreslení je možné dále upravovat, což si ukážeme příště.

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ů).

Poznámka: ve skutečnosti je ovšem možné diagram zcela otočit s tím, že tok dat (či řízení) bude probíhat zdola nahoru:
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.

Poznámka: touto tematikou se budeme podrobněji zabývat příště.

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.

Poznámka: příště si jednotlivé grafické reprezentace uzlů ukážeme.

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ů:

ict ve školství 24

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:

# Demonstrační příklad Stručný popis příkladu Cesta
1 flowchart1.py jednoduchý vývojový diagram s dvojicí uzlů (počátek a konec zpracování) https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/flow­chart1.py
2 flowchart2.py vývojový diagram s uzly typu Action a InputOutput https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/flow­chart2.py
3 flowchart3.py diagram s nastavenou orientací Top-Bottom https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/flow­chart3.py
4 flowchart4.py přímé zobrazení diagramu po spuštění skriptu https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/flow­chart4.py
       
5 onprem1.py jednoduchá pipeline tvořená Kafkou, workerem naprogramovaným v Go a message brokerem RabbitMQ https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/onprem1.py
6 onprem2.py diagram s větvením a spojením – větší množství workerů https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/onprem2.py
7 onprem2aws.py totožný diagram, ovšem používající odlišné ikony (z AWS) https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/on­prem2aws.py
8 onprem3.py změna orientace předchozího diagramu (shora dolů) https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/onprem3.py
9 onprem3B.py změna orientace předchozího diagramu (zdola nahoru) https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/onprem3B.py
10 onprem4.py složitější pipeline s větším množstvím větvení https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/onprem4.py
11 onprem5.py dvojice zdrojů dat https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/onprem5.py
12 onprem6.py zdroj a cíl dat je tvořen jediným uzlem https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/onprem6.py
13 onprem7.py zjednodušení předchozího diagramu https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/onprem7.py
14 onprem8.py více zdrojů a cílů dat, větší množství workerů https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/onprem8.py
       
15 dx.py složitější diagram s clustery https://github.com/tisnik/most-popular-python-libs/blob/master/diagrams/dx.py

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:

  1. Nástroje pro tvorbu UML diagramů
    https://www.root.cz/clanky/nastroje-pro-tvorbu-uml-diagramu/
  2. Nástroje pro tvorbu UML diagramů z příkazové řádky
    https://www.root.cz/clanky/nastroje-pro-tvorbu-uml-diagramu-z-prikazove-radky/
  3. 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/
  4. 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/
  5. 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/
  6. 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/
  7. 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/
  8. 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

  1. Flowchart (Wikipedia)
    https://en.wikipedia.org/wi­ki/Flowchart
  2. DRAKON
    https://en.wikipedia.org/wiki/DRAKON
  3. Modeling language
    https://en.wikipedia.org/wi­ki/Modeling_language
  4. Napkin na GitHubu
    https://github.com/pinetr2e/napkin
  5. Napkin 0.6.8 na PyPi
    https://pypi.org/project/napkin/
  6. PlantUML (home page)
    http://plantuml.sourceforge.net/
  7. PlantUML (download page)
    http://sourceforge.net/pro­jects/plantuml/files/plan­tuml.jar/download
  8. PlantUML (Language Reference Guide)
    http://plantuml.sourcefor­ge.net/PlantUML_Language_Re­ference_Guide.pdf
  9. Rhizome
    https://github.com/ztellman/rhizome
  10. Swagger to UML
    https://github.com/nlohman­n/swagger_to_uml
  11. pydiagrams
    https://github.com/billin­gtonm/pydiagrams
  12. graphviz(3) – Linux man page
    https://linux.die.net/man/3/graphviz
  13. dot(1) – Linux man page
    https://linux.die.net/man/1/dot
  14. neato(1) – Linux man page
    https://linux.die.net/man/1/neato
  15. twopi(1) – Linux man page
    https://linux.die.net/man/1/twopi
  16. circo(1) – Linux man page
    https://linux.die.net/man/1/circo
  17. fdp(1) – Linux man page
    https://linux.die.net/man/1/fdp
  18. sfdp(1) – Linux man page
    https://linux.die.net/man/1/sfdp
  19. Plain-text diagrams take shape in Asciidoctor!
    http://asciidoctor.org/new­s/2014/02/18/plain-text-diagrams-in-asciidoctor/
  20. Graphviz – Graph Visualization Software
    http://www.graphviz.org/
  21. graphviz (Manual Page)
    http://www.root.cz/man/7/graphviz/
  22. dot (Manual page)
    http://www.root.cz/man/1/dot/
  23. dot (Manual v PDF)
    https://graphviz.org/pdf/dot.1.pdf
  24. Ditaa home page
    http://ditaa.sourceforge.net/
  25. Ditaa introduction
    http://ditaa.sourceforge.net/#intro
  26. Ditaa usage
    http://ditaa.sourceforge.net/#usage
  27. Node, Edge and Graph Attributes
    http://www.graphviz.org/doc/in­fo/attrs.html
  28. Graphviz (Wikipedia)
    http://en.wikipedia.org/wiki/Graphviz
  29. Unified Modeling Language
    https://en.wikipedia.org/wi­ki/Unified_Modeling_Langu­age
  30. UML basics: The sequence diagram
    http://www.ibm.com/develo­perworks/rational/library/3101­.html
  31. UML 2 State Machine Diagrams: An Agile Introduction
    http://www.agilemodeling.com/ar­tifacts/stateMachineDiagram­.htm
  32. Sequence diagram (Wikipedia)
    https://en.wikipedia.org/wi­ki/Sequence_diagram
  33. UML 2 Sequence Diagrams: An Agile Introduction
    http://www.agilemodeling.com/ar­tifacts/sequenceDiagram.htm
  34. A Quick Introduction to UML Sequence Diagrams
    http://www.tracemodeler.com/ar­ticles/a_quick_introducti­on_to_uml_sequence_diagram­s/
  35. UML Sequence Diagrams
    https://www.uml-diagrams.org/sequence-diagrams.html
  36. Web Sequence Diagrams
    https://www.websequencediagrams.com/
  37. Drawing sequence diagrams “napkin style”
    https://modeling-languages.com/drawing-sequence-diagrams-napkin-style/
  38. Curated list of UML tools – 2020 edition
    https://modeling-languages.com/uml-tools/#textual
  39. Flowchart diagrams vs. UML activity diagrams
    https://stackoverflow.com/qu­estions/7081215/flowchart-diagrams-vs-uml-activity-diagrams
  40. Kopenograms – Graphical Language for Structured Algorithms
    https://kopenogram.org/As­sets/Kopenograms_Graphical_Lan­guage_for_Structured_Algo­rithms.pdf
  41. Kopenograms and Their Implementation in BlueJ
    https://link.springer.com/chap­ter/10.1007%2F978–3–319–46535–7_8
  42. The simplest way to describe your flows
    https://code2flow.com/
  43. Allan Mogensen and his Legacy
    http://www.worksimp.com/articles/allan-mogensen.htm
  44. Diagrams: Diagram as Code
    https://diagrams.mingrammer.com/
  45. Diagrams: Guides
    https://diagrams.mingrammer­.com/docs/guides/diagram
  46. Diagrams: Nodes
    https://diagrams.mingrammer­.com/docs/nodes/onprem
  47. go-diagrams
    https://github.com/blushft/go-diagrams
  48. GoJS
    https://gojs.net/latest/index.html
  49. Code visualization: How to turn complex code into diagrams
    https://www.lucidchart.com/blog/vi­sualize-code-documentation
  50. Create dependency diagrams from your code
    https://docs.microsoft.com/en-us/visualstudio/modeling/create-layer-diagrams-from-your-code?view=vs-2019
  51. Software Architecture Diagrams as Code
    https://shekhargulati.com/2020/04/21/sof­tware-architecture-diagrams-as-code/

Autor článku

Vystudoval VUT FIT a v současné době pracuje na projektech vytvářených v jazycích Python a Go.