Hálózati diagram mint kód

Az utóbbi pár évben több figyelmet fordítottam a dokumentációra. Írni egy magyarázó szöveget arról, hogy egy adott rendszer hogyan működik - ez általában elég egyszerű. Elkészíteni egy diagramot, amelyen minden kulcsfontosságú objektum és az ezek közötti kapcsolatok láthatók, szintén eléggé könnyű.

De a legproblémásabb dolog az, hogy ezt a dokumentációt folyamatosan naprakészen kell tartani. És ha csak a szövegről lenne szó, de a diagramokról... Mivel az összes dokumentáció online, tehát HTML formátumban van, a szöveghez képek gif/jpg/png formátumban csatlakoznak, amelyek valójában a diagramokat ábrázolják. A diagramokat különböző programokban, például Visio-ban vagy online szolgáltatásokban, mint a draw.io, készítjük. Aztán exportáljuk a diagramot grafikus formátumban és csatoljuk az HTML-hez. Mindez elég egyszerű.

Mi a probléma?

A diagramok általában egyszerűek. Pontosabban, nem túl bonyolultak. Igen, az objektumok száma tucatnyi, a kapcsolatoké körülbelül annyi. Plusz feliratok, különböző jelölések. Az egyszerű diagramokat szóban is el lehet mondani, de a túl bonyolultakat, hm... (c) „nem fogják érteni.” Sok diagram van, azokat időszakosan módosítani kell, tehát folyamatosan, mivel azok a termékeink fejlesztésével párhuzamosan fejlődnek.

Be lehet ágyazni HTML szolgáltatásokat. Próbáltad?

Igen, természetesen. Nekem például tetszenek a gliffy.com grafikonok. De a módosításokhoz el kell menni egy külső szolgáltatáshoz, ott javítani. Nehezebb rádelegálni egy kollégának, hogy végezze el a módosításokat.

Mit tegyünk?

Nemrégiben a GitHub-on rátaláltam egy ajánlott tárolóra github.com/RaoulMeyer/diagram-as-code. Diagram mint kód. Tehát leírjuk JS-ben a szükséges diagramot. Ezt a JS-t közvetlenül abban a HTML-ben írjuk, ahol a dokumentáció többi szövege is található.

Megjegyzem, hogy a dokumentációt nem teljesen HTML-ben írom. Általában a dokumentáció egy fájlhalmaz markdown szöveggel, amelyet aztán egy tökéletes dokumentációs webhelyre konvertálnak valamilyen motorral, például wintersmith-tel. Vagy wiki-rendszerrel.

Nagyon kényelmes: írtunk egy szöveget, majd megnyitjuk a script taget, és abban a diagram JS kódját írjuk le.

Mi az, ami megint nem stimmel?

Ez a tároló tetszett, de nem ez az egyetlen példa arra, amikor a diagramot kód vagy szöveges képviselet segítségével készítik. (A cikk végén linkek találhatók a diagram as code témakörében talált projektekhez és cikkekhez.)

És nem én vagyok az egyedüli, aki a dokumentációt szerkeszti. Néha a kollégák is hozzájárulnak - egy szó javítása, a leírás módosítása, új képek beillesztése. 

Ezért szeretném, hogy a diagram egy érthető, olvasható szöveges formátumban jelenjen meg, amelyhez nem kell sokáig tanulni. Néhol akár egyszerű másolás-beillesztés is elegendő a új séma hozzáadásának felgyorsításához. 

Egy másik kollégám azt is észrevette, hogy a kód, az persze jó, de ha a struktúrát használjuk, minden nagyon szigorú és kifejező lehet.

Ezért megpróbáltam a sémát több kisebb tömbként elképzelni, amelyek a csomópontokat, kapcsolatokat, csomópontcsoportokat és a csomópontok elhelyezkedését írják le. Szerintem elég kényelmes lett, bár persze ízlés és szín…

Hogyan lehet ez a diagram tömbben?

  • Minden csomópontot egy azonosító ír le, amely egyértelműen meghatározza a csomópontot.
  • A csomóponthoz ikont is lehet adni, valamint feliratot.
  • Két csomópont között kapcsolatot lehet megadni.
  • A kapcsolathoz a sémában színt és feliratot állíthatunk be.
  • A kapcsolat iránya a forrástól a cél felé határozható meg. A forrás és a cél csomópont-azonosítókkal van megadva.
  • Egy vagy több csomópontot csoportba is lehet sorolni.
  • A kapcsolatot csoporttól csoportig is meg lehet adni.

Ezekkel az egyszerű szabályokkal ilyen séma jön létre. Egyszerű? Teljesen.

Hálózati diagram mint kód

Ezt a következő js-kóddal írjuk le. A lényeg itt az elements objektum. Amelyben a nodes - csomópontok, edges - kapcsolatok szerepelnek.
 

  const elements = {
    nodes: [       // csomópontokat írunk le
      { id: 'client', type: 'smartphone', label: 'Mobilalkalmazás'},
      { id: 'server', type: 'server', label: 'Fő Szerver'},
      { id: 'db1', type: 'database', label: 'DB 1'},
      { id: 'db2', type: 'database', label: 'DB 2'},
    ],
    edges: [       // kapcsolatokat adunk meg
      { source: 'client', target: 'server', label: 'kérés' },
      { source: 'server', target: 'db1', label: 'kérés' },
      { source: 'server', target: 'db2', label: 'kérés' },
    ],
};
Diagram('scheme1', elements);

Természetesen a séma megrajzolását nem én találtam ki, hanem egy könyvtárat használtam. cytoscape.js — nagyon erőteljes vizualizáló eszköz. A lehetőségeinek egy részét a saját megoldásomban csupán használom. 

Nyilvánvaló, hogy ez egy egyszerű példa. Lehet bonyolultabb is?

Igen, kérem. A pozíciók megadásához positions-t, a csoportok megadásához pedig a groups listáját használjuk, az elemeknél pedig a group attribútumot.

Hálózati diagram mint kód

És ez a kód:

<div id="scheme5" style="height:500px;width:800px;"></div>
<script>
  const elements5 = {
    groups: [
      { id: 'g1', label: 'Группа сервисов 1'},
      { id: 'g2', label: 'Группа сервисов 2'},
    ],
    nodes: [
      { id: 'man1', type: 'person', label: 'Человек'},
      { id: 'client', type: 'smartphone', label: 'Смартфон'},
      { id: 'agent-backend', type: 'server', group: 'g1', label: 'agent-backend'},
      { id: 'web', type: 'server', group: 'g1', label: 'Приложение admin'},
      { id: 'www', type: 'server', group: 'g1', label: 'страница загрузки'},
      { id: 'mongodb1', type: 'database', group: 'g1', label: 'Mongo DB 1'},
      { id: 'mongodb2', type: 'database', group: 'g1', label: 'Mongo DB 2'},
      { id: 'runner-integration1', type: 'worker', group: 'g1', label: 'отправка'},
      { id: 'runner-integration2', type: 'worker', group: 'g1', label: 'отправка'},
      { id: 'api', type: 'server', group: 'g1', label: 'API'},
      { id: 'server2', type: 'server', group:'g2', label: 'сервер'},
      { id: 'otherServer', type: 'server', group:'g2', label: 'сервер'},
      { id: 'firebase', type: 'cloud', label: 'Google Firebase'},
    ],
    edges: [
      { source: 'client', target: 'agent-backend', label: 'json', color: 'red' },
      { source: 'agent-backend', target: 'mongodb1', color: 'red' },
      { source: 'agent-backend', target: 'mongodb2',  color: 'red' },
      { source: 'mongodb1', target: 'runner-integration1', label: 'данные' },
      { source: 'mongodb2', target: 'runner-integration2', label: 'данные' },
      { source: 'mongodb1', target: 'web', label: 'данные для отображения' },
      { source: 'runner-integration1', target: 'server2', label: 'данные' },
      { source: 'runner-integration2', target: 'otherServer', label: 'данные' },
      { source: 'api', target: 'firebase', label: 'запросы', color: 'blue', },
      { source: 'firebase', target: 'client', label: 'push', color: 'blue'},
      { source: 'server2', target: 'api', label: 'уведомления', color: 'blue'},
      { source: 'man1', target: 'client', },
    ],
    positions: [
      { id: 'client', row: 2, col: 1,},
      { id: 'agent-backend', row: 2, col: 3,},
      { id: 'web', row: 6, col: 3,},
      { id: 'www', row: 1, col: 3,},
      { id: 'mongodb1', row: 1, col: 4,},
      { id: 'mongodb2', row: 2, col: 5,},
      { id: 'runner-integration1', row: 3, col: 3,},
      { id: 'runner-integration2', row: 4, col: 3,},
      { id: 'api', row: 5, col: 3,},
      { id: 'server2', row: 6, col: 7,},
      { id: 'otherServer', row: 4, col: 7,},
      { id: 'firebase', row: 5, col: 1,},
      { id: 'logger', row: 2, col: 7,},
      { id: 'crm', row: 5, col: 8,},
    ],
};
  Diagram('scheme5', elements5, {layout: 'grid'});
</script>

Ez a séma egyik oldalon — majdnem egy laptopnyi kód képernyője, a másikon a json típusú struktúra lehetővé teszi az összes adat gyors és egyszerű kitöltését hasonló módon, beleértve a másolást-beillesztést is.

Miért vannak a positions külön a csomópontoktól?

Ez kényelmesebb. Először megadjuk a nodes-ot. Ezután adhatunk néhány csoportot, és megjelölhetjük őket a csomópontokban. Ezután jelöljük ki a kapcsolatokat. És csak azután, amikor az alapvető objektumok és a köztük lévő kapcsolatok már megvannak, fogunk neki az objektumok elhelyezésének a sémán. Vagy éppen ellenkezőleg.

Lehet positions nélkül is?

Lehet positions nélkül is. De ez egy kicsit zsúfolt lesz, a példákban meg lehet nézni egy ilyen verziót. Ez azért van, mert a cytoscape-nek van egy algoritmus a csomópontok elhelyezésére. fcose, amely figyelembe veszi a csoportok meglétét is. A positions megadása kontrollálhatóbbá teszi a sémát, de az első vázlat elkészítésénél positions nélkül is lehet.

A positions-t a Hadihajó stílusában is meg lehet adni. Azaz az egyik csomópont a1-ben helyezkedik el, a másik pedig d5-ben. Különösen segít, hogy a cytoscape mobilis elemeket hoz létre a canvas-on, azaz mozgathatjuk őket, megnézhetjük a különböző elhelyezési lehetőségeket, majd rögzíthetjük a kódba a tetszőleges elrendezést.

Összességében érthető. Próbálhatunk?
 
Természetesen, a sémák gyors létrehozásához csináltam egy kis szerkesztője, amely magától frissíti a sémát, és a böngészőben megőrzi az utolsó verziót (localStorage-ban).

Próbálták? Most már a saját oldalára is fel lehetne tenni.

Akkor még egyszer:

1. Csatlakoztatjuk a scriptet

<script src="https://unpkg.com/@antirek/network-diagram@0.1.4/dist/code-full.min.js"></script>

2. Hozzáadjuk a html kódhoz

<div id="scheme1" style="height:300px;width:800px;"></div>
<script>      
  const elements = {    
    nodes: [
      { id: 'client', type: 'smartphone', label: 'Mobile App'},
      { id: 'server', type: 'server', label: 'Main Server'},
      { id: 'db1', type: 'database', label: 'DB 1'},
      { id: 'db2', type: 'database', label: 'DB 2'},
    ],
    edges: [
      { source: 'client', target: 'server', label: 'request' },
      { source: 'server', target: 'db1', label: 'request' },
      { source: 'server', target: 'db2', label: 'request' },
    ],
  };
  Diagram('scheme1', elements);
</script>

3. módosítjuk a kódot a kívánt sémához (azt hiszem, ez egyszerűbb, mint baglyot rajzolni 🙂

Részletesebben a projekt oldalán GitHub-on.

Mi az összefoglaló?

Céljaimat elértem – a sémák inline dokumentációba történő beillesztése, a formátum elég egyszerű és érthető. Szupersémákhoz nem megfelelő, de a kis sémákhoz, amelyek a kapcsolatok struktúráját magyarázzák – kifejezetten jó. Mindig gyorsan módosítható, és valami idővel megváltoztatható. Igen, és a kollégák is el tudják módosítani a doksit, mint minimum az objektumok feliratait különösebb oktatás nélkül ))

Mit lehetne javítani?

Itt természetesen számos lehetőség van. További ikonok hozzáadása (az összes meglévő inline van a scriptben). Kifejezőbb ikonszett kiválasztása. Kapcsolatok vonalstílusának megadása. Háttérkép hozzáadása.

És mit gondolnak erről?
 
Már van néhány ötletem a problémák megvalósítására, kérjük, adja hozzá saját ötleteit a megjegyzésekben.

A megoldásom mindenképp alkalmazható egy szűk feladatkörben, és lehet, hogy találsz egy kényelmesebb eszközt a diagramok rajzolására, ha csak kódolod őket - ahogy mondani szokták: 'n show me your diagram as code'

  1. Jó válogatás
  2. Pompás szolgáltatás (9 típusú grafikon online szerkesztő)
  3. Конечно, mermaid.js
  4. És ha szereted a szuper részletes és bonyolult ábrákat, akkor mindenképp lenyűgöz a projekt: go.drawthe.net

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster