Nettverksdiagram som kode

I løpet av de siste par årene har jeg i større grad begynt å jobbe med dokumentasjon. Å skrive en forklarende tekst om hvordan et system fungerer – generelt sett, er dette ganske enkelt. Å tegne et diagram som viser alle viktige objekter og forbindelsene mellom disse objektene, er også ganske lett.

Men det mest problematiske punktet – er å holde dokumentasjonen oppdatert. For ok, teksten, men diagrammene... Siden all dokumentasjon er online, altså i html-format, så vedlegges tekstene bilder i gif/jpeg/png som faktisk viser diagrammene. Og diagrammene tegnes i forskjellige programmer som Visio eller nettjenester som draw.io. Deretter eksporterer man diagrammet i grafisk format og vedlegger det til html. Det er ganske enkelt.

Hva er problemet?

Diagrammene er vanligvis enkle. Snarere, ikke så veldig kompliserte. Ja, antall objekter vil være ti til tjue, antall forbindelser omtrent det samme. Pluss etiketter, noen merkinger. Enkle diagrammer kan man også beskrive med ord, men altfor kompliserte, eh… (c) «vil ikke bli forstått». Det er mange diagrammer, endringer må foretas jevnlig, altså konstant, ettersom de følger utviklingen av våre produkter.

Kan man integrere html-tjenester? Har du prøvd?

Ja, selvfølgelig. Jeg liker for eksempel grafene fra gliffy.com. Men for å gjøre endringer, må man gå til en tredjeparts tjeneste og redigere der. Og det er vanskeligere å delegere til en kollega å gjøre endringer.

Hva skal man gjøre?

Nylig kom jeg over et repositorium på github som ble anbefalt til meg github.com/RaoulMeyer/diagram-as-code. Diagram som kode. Altså, vi beskriver i js det diagrammet vi ønsker. Denne js-koden skriver vi rett i den samme html-en hvor også annen dokumentasjonstekst finnes.

For å si det slik, jeg skriver dokumentasjon ikke akkurat i html. Vanligvis er dokumentasjonen et sett med filer med markdown-tekst, som deretter konverteres til et fullt ut dokumentasjonsnettsted med en eller annen motor, for eksempel wintersmith. Eller et wiki-system.

Det viser seg å være veldig praktisk: vi har skrevet teksten, deretter åpnes script-taggen og i den er js-koden for diagrammet beskrevet.

Hva er det nå galt med?

Dette repositoriet likte jeg, men det er ikke det eneste eksempelet der diagrammet tegnes med kode eller tekstbasert representasjon. (På slutten av artikkelen vil det være lenker til prosjekter og artikler jeg har funnet om temaet diagram som kode.)

Og jeg er ikke den eneste, der redigerer dokumentationen. Nogle gange bidrager mine kolleger også med at rette ord, ændre beskrivelser og indsætte nye billeder. 

Derfor vil jeg gerne se diagrammet i et læsbart og forståeligt tekstformat, som ikke kræver lang indlæring. Og nogle steder kan man endda blot lave copy-paste for at fremskynde tilføjelsen af et nyt diagram. 

En anden kollega bemærkede, at koden er god, men at hvis man bruger en struktur, kan det hele være meget strengt og udtryksfuldt.

Derfor har jeg forsøgt at fremstille diagrammet som et sæt af flere små array, der beskriver noder, forbindelser, grupper af noder og også placeringen af noderne. Jeg synes, det er ret praktisk, selvom smag og behag…

Hvordan er diagrammet i array?

  • Hver node beskrives med en identifikator, der entydigt definerer noden.
  • Man kan også tilføje et ikon til noden, tilføje en tekst.
  • Mellem to noder kan man angive en forbindelse.
  • For forbindelsen i diagrammet kan man angive farve og tekst.
  • Retningen af forbindelsen defineres som fra kilde til mål. Kilde og mål angives med nodens identifikatorer.
  • En eller flere noder kan tilføjes til en gruppe.
  • Forbindelsen kan også angives fra en gruppe og til en gruppe.

Ved at bruge disse simple regler får man sådan et diagram. Simpelt? Helt sikkert.

Nettverksdiagram som kode

Og det beskrives med følgende js-kode. Det vigtigste her er objektet elements. Hvor noderne og forbindelserne er angivet.
 

  const elements = {
    nodes: [       // beskriver noder
      { 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: [       // angiver forbindelser
      { source: 'client', target: 'server', label: 'request' },
      { source: 'server', target: 'db1', label: 'request' },
      { source: 'server', target: 'db2', label: 'request' },
    ],
  };
  Diagram('scheme1', elements);

Selvfølgelig opfandt jeg ikke tegningen af diagrammet selv; jeg brugte en biblioteksfunktion. cytoscape.js — en meget kraftfuld visualiseringsværktøj. Hvilke muligheder jeg kun bruger en lille del af i min løsning. 

Forståeligt, det er et simpelt eksempel. Kan vi gøre det mere komplekst?

Ja, selvfølgelig. For at angive positioner bruger vi positions, til at angive grupper angiver vi listen over grupper i groups, og for selve elementerne tilføjer vi attributten group.

Nettverksdiagram som kode

Og her er koden:

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

Denne strukturen er nesten som et par skjermbilder av kode på en laptop, mens en json-lignende struktur gjør det raskt å fylle ut all informasjon analogt, og man kan copy-paste.

Hvorfor er positions separert fra nodene?

Det er mer praktisk. Først angir vi nodene. Så kan vi legge til et par grupper og indikere dem i nodene. Deretter definerer vi relasjonene. Og så, når de viktigste objektene og relasjonene er på plass, tar vi tak i posisjoneringen av disse objektene i diagrammet. Eller omvendt.

Kan vi gjøre det uten positions?

Ja, det kan gjøres uten positions. Men det vil være litt rotete; i eksemplene kan du se et slikt alternativ. Dette skyldes at cytoscape har en algoritme for å posisjonere noder. fcose, som også tar hensyn til tilstedeværelsen av grupper. Å angi positions gjør diagrammet mer kontrollert, men i den første skissestadiet kan vi klare oss uten positions.

Positioner kan også angis i stilen til sjøkrig. Det vil si at en node plasseres i a1, og en annen i d5. Spesielt nyttig er det at cytoscape lager objekter på lerretet som flyttbare, dvs. vi kan flytte dem, se forskjellige posisjoner og deretter fikse et arrangement vi liker i koden.

Generelt er det forståelig. Kan vi prøve?
 
Selvfølgelig, for rask opprettelse av diagrammer har jeg laget en liten editor, som automatisk oppdaterer diagrammet og lagrer den nyeste versjonen i nettleseren (i localStorage).

Har du prøvd? Nå kan du også legge til det på din egen side.

Da oppsummerer vi:

1. Vi kobler til skriptet

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

2. Vi legger til html-koden

<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. Vi redigerer koden til ønsket diagram (jeg tror dette er enklere enn å tegne en ugle 🙂

Mer detaljert på prosjektets side GitHub.

Hva ble resultatet?

Mine mål ble nådd — å legge til diagrammer inline i dokumentasjonen, formatet er ganske enkelt og forståelig. Det er ikke egnet for superdiagrammer, men for små diagrammer som forklarer relasjonsstrukturen, fungerer det veldig bra. Man kan alltid raskt justere og endre noe over tid. Og kollegene kan selv rette seg litt i dokumentet, i det minste etikettene til objektene uten mye opplæring))

Hva kan forbedres?

Det finnes selvsagt mange alternativer. Legge til ekstra ikoner (alle eksisterende er lagt til inline i skriptet). Finne et mer uttrykksfullt sett med ikoner. Gi mulighet for å angi stil for relasjonslinjene. Legge til bakgrunnsbilde.

Hva tenker du?
 
Eg har altfor mange idéar til gjennomføring i issues, og du må også gjerne legge til dine i kommentarane.

Løysinga mi er absolutt tilpassa eit smalt spekter av oppgåver, og du vil kanskje finne eit meir brukervennleg verktøy for å teikne diagram, berre ved å kode dei – som det blir sagt 'vis meg diagrammet ditt som kode'

  1. God samling
  2. Fabelaktig teneste (9 typar diagram i nettredigerer)
  3. Конечно, mermaid.js
  4. Og hvis du elskar super detaljerte og komplekse diagram – så vil dette prosjektet definitivt imponere deg: go.drawthe.net

Kilde: habr.com

Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere 🔥 Kjøp pålitelig hosting for nettsteder med DDoS-beskyttelse, VPS VDS-servere | ProHoster